2012-07-17 52 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