2012-07-17 187 views
2

我正在使用GUIDE在Matlab中创建GUI。当用户点击GUI中的“开始”按钮时,它会在无限循环中运行的后台启动优化任务。每次迭代它都会向GUI输出一些信息。Matlab GUI中的无限循环导致Matlab在GUI关闭时冻结?

当我按下该开始按钮,然后关闭GUI窗口Matlab冻结。当我运行GUI但不按下“开始”按钮并关闭GUI时,它不会冻结。

我该如何避免冻结?

+0

我会说,不打“开始”按钮......不过玩笑归玩笑,我相信你能接受什么样展示对您的“开始”按钮,或者在回调函数执行进一步的帮助该优化任务。考虑在这两个函数中设置一些断点用于调试 – Drodbar 2012-07-18 00:24:29

+0

如果粘贴的代码太多并且仍然可读,那么使用文档共享站点(如Dropbox)可能是个好主意。如果您通过我的个人资料中的地址向我发送电子邮件,我不会有任何问题。 – 2012-07-18 03:23:31

+0

@BenA。我会尽快更新我的问题。我会尽量将我的代码简化为说明问题所需的最小代码,并在此处简化代码。 – drasto 2012-07-18 09:48:16

回答

1

正如tmpearcehis answer为了注意到函数(回调)被打断它必须包含调用的DrawNow,图,的getFrame,暂停或WAITFOR。并且按钮GUI组件上的属性interruptible必须设置为on

所以我把暂停放在无穷无尽的循环中。然而它并不好:pause(0.0000000000000001)的确显着减慢了进度(我测量了它,所以它不是主观的)。 pause(0)没有减慢周期,并允许GUI更新,但不允许在按下另一个按钮后执行任何其他回调。

我最终在周期内使用了drawnow;命令。它并没有显着减慢周期(低于5%的速度减慢),并且GUI按预期工作。

2

您开始的无限循环不允许处理任何其他事件(即窗口关闭事件)。你需要允许发生interrupt机制 - 虽然'interruptible'属性默认为'on',你必须满足其他要求:

如果其回调执行 是关于对象的可中断属性,回调可中断。但是,仅当它或其触发的函数调用drawnow,figure, getframe,pause或waitfor时才中断 。在执行定义的任务之前,这些函数处理事件队列中的所有事件,包括等待回调的任何 。如果正在执行的回调函数或触发器函数不会调用这些函数,则不管其对象的可中断属性的值如何,都不会中断 。

既然你有一个循环,你可以插入一个pausedrawnow命令,让MATLAB来处理其他事件,如其他按钮的鼠标点击(pause(0)可能工作 - 没有测试 - 允许检查中断如果没有中断,事实上不会导致循环变慢)。

(旁注:CTRL-C跳出循环,所以你总是可以做到这一点,但...不理想)

+0

谢谢,很好的答案。我已经像使用暂停一样暂停(0.0001),并且它可以工作,但显着减缓了优化周期...使用'pause(0)'不会减慢进度并允许GUI更新,但它不会阻止整个Matlab冻结时,我关闭我的GUI窗口。 你有任何建议如何不放慢进度,但为了防止关闭窗口后冻结?感谢您的任何想法 – drasto 2012-07-18 09:55:37

+0

添加你的备注:如果主Matlab窗口无响应,我无法'ctrl-c' - 这正是如果我关闭了我的GUI窗口会发生什么...... – drasto 2012-07-18 10:56:52

+1

一旦你得到GUI来响应,你可以设置'closeRequestFcn'回调来摆脱循环。这是我最好的猜测,你需要做什么。 2)是的,我关于ctrl-c的说明指的是在关闭窗口之前进行*,而不是一旦matlab停止响应。 – tmpearce 2012-07-18 14:05:40

0

我才知道,只是用事先matlabpool将让您的图形用户界面响应。基本上它会自动把你的计算放在工作者线程中。

很抱歉找不到参考。但是,也许你愿意尝试魔法;)

2

我还发现,GUI可以因为在MATLAB内存碎片变得反应迟钝不休 运行时说后100K迭代我释放所有不必要的临时变量并保存结果后,要.MAT文件 指示GUI给力退出 并从autohotkey打开一个新副本,并加载previous.mat文件中的所有以前的变量 GUI现在适用于无限循环

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