我正在使用 GUIDE 在 Matlab 中创建 GUI。当用户点击 GUI 中的“开始”按钮时,它会在后台启动以无限循环运行的优化任务。每次迭代它都会向 GUI 输出一些信息。
当我按下该开始按钮然后关闭 GUI 窗口时,Matlab 冻结。当我运行 GUI 但不按“开始”按钮并关闭 GUI 时,它不会冻结。
我怎样才能避免冻结?
我正在使用 GUIDE 在 Matlab 中创建 GUI。当用户点击 GUI 中的“开始”按钮时,它会在后台启动以无限循环运行的优化任务。每次迭代它都会向 GUI 输出一些信息。
当我按下该开始按钮然后关闭 GUI 窗口时,Matlab 冻结。当我运行 GUI 但不按“开始”按钮并关闭 GUI 时,它不会冻结。
我怎样才能避免冻结?
您开始的无限循环不允许处理任何进一步的事件(即窗口关闭事件)。您需要允许中断机制发生 - 尽管'interruptible'
属性默认为'on'
,但您必须满足另一个要求:
如果正在执行回调的对象的 Interruptible 属性为 on,则可以中断回调。但是,只有当它或它触发的函数调用drawow、figure、getframe、pause 或waitfor 时,它才会被中断。在执行其定义的任务之前,这些函数会处理事件队列中的任何事件,包括任何等待回调。如果正在执行的回调或它触发的函数没有调用这些函数,则无论其对象的 Interruptible 属性的值如何,它都不能被中断。
由于您有一个循环,您可以插入一个pause
ordrawnow
命令以允许 MATLAB 处理其他事件,例如鼠标单击其他按钮(pause(0)
可能有效 - 尚未测试 - 允许检查中断事件而不会实际导致循环变慢 if没有中断)。
(旁注: ctrl-c 打破循环,所以你总是可以这样做,但......不理想。)
我还发现,当在 100K 次迭代后无休止地运行时,由于 matlab 中的内存碎片,GUI 可能会变得无响应我释放了所有不必要的临时变量并将结果保存到 .mat 文件,之后指示 gui 强制退出并打开一个新副本从 autohotkey 并从 previous.mat 文件加载所有以前的变量 GUI 现在可以无限循环
正如tmpearce在他的回答中指出的那样,为了中断函数(回调),它必须包含对 drawow、figure、getframe、pause 或 waitfor 的调用。并且interruptible
必须on
在按钮 GUI 组件上设置属性。
所以我把暂停放在无限(无尽)循环中。但是它效果不佳:pause(0.0000000000000001)
确实显着减慢了进度(我确实对其进行了测量,因此它不是主观的)。pause(0)
没有减慢循环并允许 GUI 更新,但不允许在按下另一个按钮后执行任何其他回调。
我最终drawnow;
在循环中使用了命令。它并没有显着减慢周期(减慢不到 5%),并且 GUI 按预期工作。
我了解到,仅matlabpool
事先使用将使您的 gui 响应。基本上它会自动将您的计算放入工作线程中。
不幸的是,现在找不到参考。但也许你愿意尝试黑魔法;)
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