在用户界面周围传递数据

大多数高级用户界面要求用户能够在构成用户界面的各种功能之间传递信息。MATLAB 有许多不同的方法可以做到这一点。

guidata

MATLAB 自己的 GUI 开发环境(GUIDE) 更喜欢使用名为 handlesstruct 在回调之间传递数据。此 struct 包含各种 UI 组件的所有图形句柄以及用户指定的数据。如果你没有使用自动传递 handles 的 GUIDE 创建的回调,你可以使用 guidata 检索当前值

% hObject is a graphics handle to any UI component in your GUI
handles = guidata(hObject);

如果要修改存储在此数据结构中的值,则可以进行修改,但必须将其存储在 hObject 中,以便其他回调可以看到更改。你可以通过为 guidata 指定第二个输入参数来存储它。

% Update the value
handles.myValue = 2;

% Save changes
guidata(hObject, handles)

hObject 的值无关紧要,只要它是同一个 figure的 UI 组件*,*因为最终数据存储在包含 hObject 的图中。

最适合:

  • 存储 handles 结构,你可以在其中存储 GUI 组件的所有句柄。
  • 存储大多数回调需要访问的其他变量。

不推荐用于

  • 存储不必由所有回调和子功能访问的大变量(对于这些使用 setappdata / getappdata)。

setappdata / getappdata

guidata 方法类似,你可以使用 setappdatagetappdata 来存储和检索图形句柄中的值。使用这些方法的优点是,你只能检索所需的值,而不是包含所有存储数据的整个 struct 。它类似于键/值存储。

在图形对象中存储数据

% Create some data you would like to store
myvalue = 2

% Store it using the key 'mykey'
setappdata(hObject, 'mykey', myvalue)

并从不同的回调中检索相同的值

value = getappdata(hObject, 'mykey');

注意: 如果在调用 getappdata 之前没有存储任何值,它将返回一个空数组([])。

guidata 类似,数据存储在包含 hObject 的图中。

最适合:

  • 存储不必由所有回调和子函数访问的大变量。

UserData

每个图形句柄都有一个特殊的属性 UserData,它可以包含你想要的任何数据。它可能包含一个单元阵列,一个 struct,甚至一个标量。你可以利用此属性并在此字段中存储你希望与给定图形句柄关联的所有数据。如果你使用的是 R2014b 或更新版本,则可以使用标准 get / set 方法保存和检索图形对象或点符号。

% Create some data to store
mydata = {1, 2, 3};

% Store it within the UserData property
set(hObject, 'UserData', mydata)

% Of if you're using R2014b or newer:
% hObject.UserData = mydata;

然后从另一个回调中,你可以检索此数据:

their_data = get(hObject, 'UserData');

% Or if you're using R2014b or newer:
% their_data = hObject.UserData;

最适合:

  • 存储具有有限范围的变量(可能仅由存储它们的对象使用的变量,或与其具有直接关系的对象)。

嵌套函数

在 MATLAB 中,嵌套函数可以读取和修改父函数中定义的任何变量。这样,如果将回调指定为嵌套函数,它可以检索和修改主函数中存储的任何数据。

function mygui()    
    hButton = uicontrol('String', 'Click Me', 'Callback', @callback);

    % Create a counter to keep track of the number of times the button is clicked
    nClicks = 0;

    % Callback function is nested and can therefore read and modify nClicks
    function callback(source, event)
        % Increment the number of clicks
        nClicks = nClicks + 1;

        % Print the number of clicks so far
        fprintf('Number of clicks: %d\n', nClicks);
    end
end

最适合:

  • 小而简单的 GUI。 (为了快速原型设计,不必实现 guidata 和/或 set/getappdata 方法)。

不推荐用于

  • 中型,大型或复杂的 GUI。

  • 使用 GUIDE 创建的 GUI。

显式输入参数

如果需要将数据发送到回调函数而不需要修改回调中的数据,则始终可以考虑使用精心设计的回调定义将数据传递给回调。

你可以使用添加输入的匿名函数

% Create some data to send to mycallback
data = [1, 2, 3];

% Pass data as a third input to mycallback
set(hObject, 'Callback', @(source, event)mycallback(source, event, data))

或者你可以使用单元格数组语法指定回调,再次指定其他输入。

set(hObject, 'Callback', {@mycallback, data})

最适合:

  • 当回调需要 data 执行某些操作但是 data 变量不需要修改并保存在新状态中。