我正在使用GUIDE在Matlab中创建GUI。当用户点击GUI中的“开始”按钮时,它会在无限循环中运行的后台启动优化任务。每次迭代都会向GUI输出一些信息。
当我按下该开始按钮然后关闭GUI窗口时,Matlab会冻结。当我运行GUI但不按“开始”按钮并关闭GUI时它不会冻结。
我怎样才能避免冻结?
答案 0 :(得分:2)
您启动的无限循环不允许处理任何其他事件(即窗口关闭事件)。您需要允许interrupt机制发生 - 虽然'interruptible'
属性默认为'on'
,但您必须满足另一个要求:
如果正在执行回调的对象的Interruptible属性 如果打开,则可以中断回调。但是,它被打断了 只有当它或它触发的功能时,才会调用drawow,图, getframe,pause或waitfor。在执行他们定义的任务之前 这些函数处理事件队列中的任何事件,包括任何事件 等待回调。如果正在执行回调,还是一个函数呢 触发器,不调用这些函数,它不能被中断 无论其对象的可中断属性的值如何。
由于你有一个循环,你可以插入pause
或drawnow
命令以允许MATLAB处理其他事件,例如鼠标点击其他按钮(pause(0)
可能有效 - 避风港测试 - 允许检查中断事件,如果没有中断,实际上不会导致循环减慢。
(旁注:ctrl-c突破循环,所以你总是这样做但......不理想。)
答案 1 :(得分:2)
我还发现GUI在无休止地运行时会因为matlab中的内存碎片而变得无法响应 在说100K迭代后,我释放了所有不必要的和临时的变量,并将结果保存到.mat文件中 之后指示gui强制戒掉 并从autohotkey打开一个新副本并加载来自previous.mat文件的所有先前变量 GUI现在可以无限循环
答案 2 :(得分:1)
正如tmpearce中his answer所指出的那样,为了使函数(回调)被中断,它必须包含对drawow,figure,getframe,pause或waitfor的调用。并且属性interruptible
必须在按钮GUI组件上设置为on
。
所以我把暂停放在无限(无尽)循环中。然而它没有奏效:pause(0.0000000000000001)
确实显着减慢了进度(我确实测量了它,因此它不是主观的)。 pause(0)
没有减慢周期并允许GUI更新,但是在按下另一个按钮后不允许执行任何其他回调。
我最终在循环中使用了drawnow;
命令。它没有显着减慢周期(减慢不到5%)并且GUI按预期工作。
答案 3 :(得分:0)
我了解到,事先使用matlabpool
会让你的gui保持敏感。基本上它会自动将您的计算放在工作线程中。
遗憾的是现在找不到参考。但也许你愿意尝试黑魔法;)
答案 4 :(得分:0)
matlab guis有很多对象。关闭GUI时,对象会消失。
有时,在窗口关闭并且程序继续运行后,线程将保留。
要关闭此线程,我使用嵌入我的gui中的轴,并确保它仍然存在于每个循环中。
h=gca;
for x = 1:WIDTH:(size(image,1)-WIDTH-OVERLAP-1)
for y = 1:HEIGHT:(size(image,2)-HEIGHT-OVERLAP-1)
%if the main gui closes, then the axis will change...
%in that case, you should stop this thread.
if(h == gca)
window = image(x:x+WIDTH+OVERLAP,y:y+HEIGHT+OVERLAP);%%account for a 10 pixel overlap
imshow(window)
pause(.01);
else
close all;
return;
end
end
end