2008-11-07 74 views
5

是否可以從函數內部寫入GUI?如何在MATLAB中創建一個函數內的GUI?

問題是所有GUI函數的回調都在全局工作空間中進行評估。但函數有自己的工作空間,不能訪問全局工作空間中的變量。是否有可能使GUI功能使用該功能的工作區?例如:

function myvar = myfunc() 
    myvar = true; 
    h_fig = figure; 

    % create a useless button 
    uicontrol(h_fig, 'style', 'pushbutton', ... 
         'string', 'clickme', ... 
         'callback', 'myvar = false'); 

    % wait for the button to be pressed 
    while myvar 
     pause(0.2); 
    end 

    close(h_fig); 

    disp('this will never be displayed'); 
end 

此事件循環將無限期地運行,因爲在函數的回調將不會修改myvar。相反,它會在全局工作區中創建一個新的myvar

回答

5

有許多方法可以通過使用App Designer,GUIDE或以編程方式創建它(我將在下面說明該選項)build a GUI。瞭解用於GUI組件的different ways to define callback functions以及options available for sharing data between components也很重要。

我偏愛的方法是使用nested functions作爲回調。這裏有一個簡單的GUI爲例:

function make_useless_button() 

    % Initialize variables and graphics: 
    iCounter = 0; 
    hFigure = figure; 
    hButton = uicontrol('Style', 'pushbutton', 'Parent', hFigure, ... 
         'String', 'Blah', 'Callback', @increment); 

    % Nested callback function: 
    function increment(~, ~) 
    iCounter = iCounter+1; 
    disp(iCounter); 
    end 

end 

當你運行該代碼,顯示計數器應當由一個每按一次按鈕增加,因爲嵌套函數increment訪問的make_useless_button工作空間,因此可以修改iCounter。請注意,按鈕回調設置爲function handleincrement,並且此函數默認情況下必須接受兩個參數:觸發回調的UI組件的圖形句柄以及關聯事件數據的結構。在這種情況下,我們ignore them with the ~因爲我們沒有使用它們。

擴展上面的方法您的具體問題,你可以添加你的循環和改變的回調,因此設置你的標誌變量設置爲false:

function make_stop_button() 

    % Initialize variables and graphics: 
    keepLooping = true; 
    hFigure = figure; 
    hButton = uicontrol('Style', 'pushbutton', 'Parent', hFigure, ... 
         'String', 'Stop', 'Callback', @stop_fcn); 

    % Keep looping until the button is pressed: 
    while keepLooping, 
    drawnow; 
    end 

    % Delete the figure: 
    delete(hFigure); 

    % Nested callback function: 
    function stop_fcn(~, ~) 
    keepLooping = false; 
    end 

end 

drawnow這裏需要給按鍵回調機會中斷循環內的程序流並修改keepLooping的值。

1

你可以在GUI代碼中聲明一個變量全局函數和全局變量,當然如果回調是在一個單獨的函數中而不是內聯的。我在一個用於製作快速菜單系統的小型骨架GUI中完成了這個任務。

在你上面的代碼你可以向全球關鍵字添加到您的初始宣佈和也你的網線回調即「全球MYVAR =假」

+0

OP將需要將輸出變量更改爲其他值,並在基工作區中創建「全局myvar」以使其工作。 – Azim 2008-11-07 17:29:26

+0

這真的是唯一的方法嗎?對於這項工作來說,使用全局變量似乎有點生硬。 – bastibe 2008-11-08 08:55:55

1

我找到了一個解決問題的辦法。回調函數必須修改GUI的句柄結構。

function myfunc() 
    h_fig = figure; 

    % add continue_loop to the GUI-handles structure 
    fig_handles = guihandles(h_fig); 
    fig_handles.continue_loop = true; 
    guidata(h_fig, fig_handles); 

    % create a useless button 
    uicontrol(h_fig, 'style', 'pushbutton', ... 
         'string', 'clickme', ... 
         'callback', @gui_callback); 

    % wait for the button to be pressed 
    while fig_handles.continue_loop 
     fig_handles = guidata(h_fig); % update handles 
     pause(0.2); 
    end 

    close(h_fig); 
    disp('callback ran successfully'); 
end 

% The arguments are the Matlab-defaults for GUI-callbacks. 
function gui_callback(hObject, eventdata, handles) 
    % modify and save handles-Structure 
    handles.continue_loop = false; 
    guidata(hObject, handles); 
end 

注意,因爲在運行時的while循環只會更新fig_handles,你將永遠有:這種結構既可以在回調中,並從功能,而不會引入新的變量,以全球的工作區訪問至少0.2秒的延遲,直到循環獲得修改爲止fig_handles.continue_loop

相關問題