Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

在回调之间共享数据

数据共享方法概述

许多 App 包含相互依赖的控件、菜单和图形对象。由于每个回调函数都有自己的作用域,因此必须显式与 App 中需要访问数据的部分共享数据。下表描述了在 App 内共享数据的几种不同方法。

方法说明要求和取舍
在 UserData 或其他对象属性中存储数据

直接通过组件对象获取或设置属性值。

所有 UI 组件都有一个可存储任意 MATLAB® 数据的 UserData 属性。

  • 需要访问组件以设置或检索属性。

  • UserData 一次仅保存一个变量,但可以将多个值作为 struct 数组或元胞数组进行存储。

将数据存储为应用程序数据

使用 setappdata 函数将数据与特定组件关联。可以稍后使用 getappdata 函数来访问它。

  • 要求访问组件以设置或检索应用程序数据。

  • 可以共享多个变量。

创建嵌套回调函数

在主函数内嵌套回调函数。这将为回调函数提供主函数中所有变量的访问权限。

  • 要求在与主函数相同的文件中编码回调函数。

  • 可以共享多个变量。

使用 guidata 函数存储数据

使用 guidata 函数与图窗窗口共享数据。

  • 通过任意 UI 组件存储或检索数据。

  • 一次仅存储一个变量,但可以将多个值作为 struct 数组或元胞数组进行存储。

在 UserData 或其他对象属性中存储数据

UI 组件在其属性中包含了有用的信息。例如,可以通过查询滑块的 Value 属性来查找滑块的当前位置。此外,所有组件都有 UserData 属性,其中可存储任意 MATLAB 变量。所有回调函数只要能够访问组件,就能访问存储在 UserData 属性中的值。

在使用传统图窗创建的 App 中共享用户数据

使用圆点表示法来设置和查询传统图窗的属性。

hfig = figure;
figname = hfig.Name;
hfig.Name = 'My Window';

如果您的代码没有组件的直接访问权限,请使用 findobj 函数来搜索该组件。如果搜索成功,findobj 将会返回该组件作为输出。然后您就可以访问该组件的属性。

以下 App 代码使用 UserData 属性来共享关于滑块的信息。要查看其工作方式,请将以下代码复制并粘贴到编辑器中,然后运行该代码。

function my_slider()
hfig = figure();
slider = uicontrol('Parent', hfig,'Style','slider',...
         'Units','normalized',...
         'Position',[0.3 0.5 0.4 0.1],...
         'Tag','slider1',...
         'UserData',struct('val',0,'diffMax',1),...
         'Callback',@slider_callback);
     
button = uicontrol('Parent', hfig,'Style','pushbutton',...
         'Units','normalized',...
         'Position',[0.4 0.3 0.2 0.1],...
         'String','Display Difference',...
         'Callback',@button_callback);
end

function slider_callback(hObject,eventdata)
	sval = hObject.Value;
	diffMax = hObject.Max - sval;
	data = struct('val',sval,'diffMax',diffMax);
	hObject.UserData = data;
end

function button_callback(hObject,eventdata)
	h = findobj('Tag','slider1');
	data = h.UserData;
	display([data.val data.diffMax]);
end
当用户移动滑块时,slider_callback 将会使用以下命令在结构体中存储数据:

  • data = struct('val',sval,'diffMax',diffMax) 在名为 data 的结构体中存储值 svaldiffMax

  • hObject.UserData = data 在滑块的 UserData 属性中存储 data 的值。

当用户点击普通按钮时,button_callback 使用以下命令来检索数据:

  • h = findobj('Tag','slider1') 查找滑块组件。

  • data = h.UserData 获取滑块 UserData 属性的值。

将数据存储为应用程序数据

要存储应用程序数据,请调用 setappdata 函数:

setappdata(obj,name,value);
第一个输入 obj 是用于存储数据的组件对象。第二个输入 name 是描述值的友好名称。第三个输入 value 是需要存储的值。

要检索应用程序数据,请使用 getappdata 函数:

data = getappdata(obj,name);
组件 obj 必须是包含数据的组件对象。第二个输入 name 必须与用于存储数据的名称相匹配。UserData 属性仅保存一个变量,而使用 setappdata 可以存储多个变量。

共享应用程序数据

以下 App 使用应用程序数据共享两个值。要查看其工作方式,请将以下代码复制并粘贴到编辑器中,然后运行该代码。

function my_slider()
hfig = figure();
setappdata(hfig,'slidervalue',0);
setappdata(hfig,'difference',1);

slider = uicontrol('Parent', hfig,'Style','slider',...
         'Units','normalized',...
         'Position',[0.3 0.5 0.4 0.1],...
         'Tag','slider1',...
         'Callback',@slider_callback);
     
button = uicontrol('Parent', hfig,'Style','pushbutton',...
         'Units','normalized',...
         'Position',[0.4 0.3 0.2 0.1],...
         'String','Display Values',...
         'Callback',@button_callback);
end

function slider_callback(hObject,eventdata)
	diffMax = hObject.Max - hObject.Value;
	setappdata(hObject.Parent,'slidervalue',hObject.Value);
	setappdata(hObject.Parent,'difference',diffMax);
end

function button_callback(hObject,eventdata)
	currentval = getappdata(hObject.Parent,'slidervalue');
	diffval = getappdata(hObject.Parent,'difference');
	display([currentval diffval]);
end
当用户移动滑块时,slider_callback 函数将会计算 diffMax。然后,它使用这些命令来修改应用程序数据:

  • setappdata(hObject.Parent,'slidervalue',hObject.Value) 使用名称 'slidervalue' 存储图窗中的当前滑块值。在本例中,hObject.Parent 为图窗。

  • setappdata(parentfig,'difference',diffMax) 使用名称 'difference' 存储图窗中的 diffMax

当用户点击普通按钮时,button_callback 函数将会使用以下命令检索数据:

  • currentval = getappdata(hObject.Parent,'slidervalue') 从图窗检索当前滑块值。在本例中,hObject.Parent 为图窗。

  • diffval = getappdata(hObject.Parent,'difference') 从图窗检索差异值。

创建嵌套回调函数

您可以在编程式 App 的主函数内嵌套回调函数。这样做时,嵌套的回调函数将会与主函数共享工作区。因此,嵌套的函数可以访问在主函数中定义的所有 UI 组件和变量。以下示例代码使用嵌套的函数共享关于滑块位置的数据。要查看其工作方式,请将以下代码复制并粘贴到编辑器中,然后运行该代码。

function my_slider()
	hfig = figure();
	data = struct('val',0,'diffMax',1);
	slider = uicontrol('Parent', hfig,'Style','slider',...
         'Units','normalized',...
         'Position',[0.3 0.5 0.4 0.1],...
         'Tag','slider1',...
         'Callback',@slider_callback);
     
	button = uicontrol('Parent', hfig,'Style','pushbutton',...
         'Units','normalized',...
         'Position',[0.4 0.3 0.2 0.1],...
         'String','Display Difference',...
         'Callback',@button_callback);

	function slider_callback(hObject,eventdata)
		sval = hObject.Value;
		diffMax = hObject.Max - sval;
		data.val = sval;
		data.diffMax = diffMax;
	end

	function button_callback(hObject,eventdata)
		display([data.val data.diffMax]);
	end
end
主函数定义了一个名为 datastruct 数组。当用户移动滑块时,slider_callback 函数将会更新 data 结构体的 valdiffMax 字段。当最终用户点击普通按钮时,button_callback 函数将会显示存储在 data 中的值。

使用 guidata 函数存储数据

guidata 函数提供了一种与图窗窗口共享数据的方法。您可以通过 hObject 组件在任意回调中存储或检索您的数据。这意味着,与使用 UserData 或应用程序数据不同,您不需要访问一个特定的组件就能设置或获取数据。使用两个输入参数调用 guidata 以存储数据:

guidata(object_handle,data);
第一个输入 object_handle 是任意 UI 组件(通常为 hObject)。第二个输入 data 是要存储的变量。每次使用两个输入参数调用 guidata 时,MATLAB 都会覆盖任何之前存储的数据。这意味着一次只能存储一个变量。如果想要共享多个值,则需将数据存储为 struct 数组或元胞数组。

要检索数据,请使用一个输入参数和一个输出参数调用 guidata

data = guidata(object_handle);
指定用于存储数据的组件与用于检索数据的组件不需要为同一组件。

如果您的数据被存储为 struct 数组或元胞数组,并且您希望更新一个元素而不更改其他元素,则应检索该数据并将其替换为修改的数组:

data = guidata(hObject);
data.myvalue = 2;
guidata(hObject,data);

使用 guidata 存储和共享数据

要在编程式 App 中使用 guidata,可在主函数中存储一些初始值数据。然后,可以在任意回调函数中检索和修改该数据。

以下代码是一个简单的编程式 App 示例,它使用 guidata 共享包含两个字段的结构体。要查看其工作方式,请将以下代码复制并粘贴到编辑器中,然后运行该代码。

function my_slider()
hfig = figure();
guidata(hfig,struct('val',0,'diffMax',1));
slider = uicontrol('Parent', hfig,'Style','slider',...
         'Units','normalized',...
         'Position',[0.3 0.5 0.4 0.1],...
         'Tag','slider1',...
         'Callback',@slider_callback);
     
button = uicontrol('Parent', hfig,'Style','pushbutton',...
         'Units','normalized',...
         'Position',[0.4 0.3 0.2 0.1],...
         'String','Display Values',...
         'Callback',@button_callback);
end

function slider_callback(hObject,eventdata)
	data = guidata(hObject);
	data.val = hObject.Value;
	data.diffMax = hObject.Max - data.val;
	guidata(hObject,data);
end

function button_callback(hObject,eventdata)
	data = guidata(hObject);
	display([data.val data.diffMax]);
end
当用户移动滑块时,slider_callback 函数将会执行以下命令,以检索和修改存储的数据:

  • data = guidata(hObject) 检索存储为结构体的数据。

  • data.diffMax = maxval - data.val 修改结构体中的 diffMax 字段。

  • guidata(hObject,data) 存储修改的结构体。

当用户点击普通按钮时,button_callback 函数将会调用 guidata 来检索存储的结构体副本。然后,它会显示存储在结构体中的两个值。

相关主题