2011-12-16 53 views
2
回調函數

假設以下簡單的例子:傳遞的實際值在Matlab

f = figure; 
plot(-10:10, (-10:10).^3, '*-r'); 
x = 1; 
y = 1; 
set(f, 'ResizeFcn', {@resizeCallback2, x, y}); 

while 1 
    [x, y, button] = ginput(1); 
    if(button ~= 1) 
     break; 
    end 

    set(f, 'ResizeFcn', {@resizeCallback2, x, y}); 
end 

%%-------------------------- 
function resizeCallback2(hFig, ~, foo, bar)  
    foo 
    bar 
end 

有沒有更簡單的方法總是通過X和Y的回調函數實際 *值,而不是具有總是在循環中更新它? 謝謝!

+0

到類似的[我的問題](http://stackoverflow.com/問題/ 22624944 /如何對創建-AN-閉合功能合MATLAB的作爲合蟒和 - js的?noredirect = 1個#comment34455498_22624944) – SolessChong 2014-03-25 05:05:25

回答

4

它看起來像是試圖存儲鼠標單擊位置的值,然後將這些值用作調整大小函數(稍後會調用)的一部分。我會做出一些改變。

首先,不是使用while循環,而是使用另一個回調捕獲鼠標單擊。例如,您可以使用數字ButtonDownFcn回調來觸發一個函數,該函數旨在將鼠標位置捕獲到某個位置。

其次,有更好的方法來存儲鼠標的位置,正確的方式將取決於你的技能水平和你的程序的需求。其中一些存儲數據的方法是:

  1. 在另一個回調的參數中,就像您現在所做的一樣。這很痛苦,但它可能起作用。所以你可以保留它,如果它足夠滿足你的需求。

  2. 大多數Matlab對象中的'userdata'字段。有幾個人提出了這個問題,並且它會正常工作。我不喜歡依賴這個,因爲我總是擔心其他一些工具也想使用userdata字段,並且這些工具會覆蓋數據。

  3. A global變量值。我也不喜歡使用全局變量,出於同樣的原因,我不喜歡使用userdata字段。但無論如何globals有時是最好的解決方案。如果您一次只有一個數字,這可能是您的問題的最簡單,最省力的解決方案。 (多圖會驅使你走向userdata解決方案,最簡單的解決方案。)

  4. 提供一個handle類來存儲一些數據(即x和y),並給予類的副本到兩個回調(ButtonDownFcnResizeFcn)。這允許兩個函數傳遞數據,而不會污染其他人的名字空間。這是我最喜歡的解決這類問題的方法,所以我會在下面給出更詳細的描述。


要執行選項(4)以上就需要一個類來存儲看起來像這樣的數據:

classdef ApplicationData < handle 
     properties (SetAccess = public, GetAccess = public) 
      x = []; 
      y = []; 
     end 
    end 

注意,因爲ApplicationData延伸handle,MATLAB將其視爲傳遞引用對象,這對我們很有用。

然後您可以創建這個類的一個實例,並把它送給每一個回調函數。

dataPassing = ApplicationData; 
    set(f, 'ButtonDownFcn', @(x,y) mouseClickCapture(x,y,dataPassing)); 
    set(f, 'ResizeFcn',  @(x,y) resizeCallback2(x,y, dataPassing)); 

mouseClickCapture看起來是這樣的:

function mouseClickCapture(hAxis, ignored, dataPassingClass) 
    mousePositionData = get(hAxis,'CurrentPoint'); 
    dataPassingClass.x = mousePositionData(1,1); 
    dataPassingClass.y = mousePositionData(1,2); 

而且你resizeCallback2看起來是這樣的:

function resizeCallback2(h, ignored, dataPassingClass) 
    %Do something here using 
    %dataPassingClass.x 
    %and 
    %dataPassingClass.y 
3

我不知道你實際上試圖做 - 也許你簡單的例子已經掩蓋你的真實意圖 - 但不是重複設置ResizeFcn的新版本,你能不能只儲存東西的UserData財產該數字,並有你的ResizeFcn閱讀,當它被執行?

+0

我同意,該標準模式是使用`UserData` 。它比改變`ResizeFcn`更清晰。 – Nzbuu 2011-12-16 09:58:34

+0

謝謝,不知道有這樣一個領域來存儲的東西......但我仍然不得不更新每次迭代中的UserData的值。 – tim 2011-12-16 12:28:41