Share Data Among Callbacks

Overview of Data Sharing Techniques

Many apps contain interdependent controls, menus, and graphics objects. Since each callback function has its own scope, you must explicitly share data with those parts of your app that need to access it. The table below describes several different methods for sharing data within your app.

MethodDescriptionRequirements and Trade-Offs
Store Data in UserData or Other Object Properties

Get or set property values directly through the component object.

All UI components have a UserData property that can store any MATLAB® data.

  • Requires access to the component to set or retrieve the properties.

  • UserData holds only one variable at a time, but you can store multiple values as a struct array or cell array.

Store Data as Application Data

Associate data with a specific component using the setappdata function. You can access it later using the getappdata function.

  • Requires access to the component to set or retrieve the application data.

  • Can share multiple variables.

Create Nested Callback Functions

Nest your callback functions inside your main function. This gives your callback functions access to all the variables in the main function.

  • Requires callback functions to be coded in the same file as the main function.

  • Can share multiple variables.

Store Data Using the guidata Function

Share data with the figure window using the guidata function.

  • Stores or retrieves the data through any UI component.

  • Stores only one variable at a time, but you can store multiple values as a struct array or cell array.

Store Data in UserData or Other Object Properties

UI components contain useful information in their properties. For example, you can find the current position of a slider by querying its Value property. In addition, all components have a UserData property, which can store any MATLAB variable. All callback functions can access the value stored in the UserData property as long as those functions can access the component.

Share User Data in Apps Created With Traditional Figures

Use dot notation to set and query properties of the traditional figure.

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

If your code does not have direct access to a component, use the findobj function to search for that component. If the search is successful, findobj returns the component as output. Then you can access the component’s properties.

The following app code uses the UserData property to share information about the slider. To see how it works, copy and paste this code into an editor and run it.

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
When the user moves the slider, the slider_callback uses these commands to store data in a structure:

  • data = struct('val',sval,'diffMax',diffMax) stores the values, sval and diffMax, in a structure called data.

  • hObject.UserData = data stores the value of data in the UserData property of the slider.

When the user clicks the push button, the button_callback uses these commands to retrieve the data:

  • h = findobj('Tag','slider1') finds the slider component.

  • data = h.UserData gets the value of the slider’s UserData property.

Store Data as Application Data

To store application data, call the setappdata function:

setappdata(obj,name,value);
The first input, obj, is the component object in which to store the data. The second input, name, is a friendly name that describes the value. The third input, value, is the value you want to store.

To retrieve application data, use the getappdata function:

data = getappdata(obj,name);
The component, obj, must be the component object containing the data. The second input, name, must match the name you used to store the data. Unlike the UserData property, which only holds only one variable, you can use setappdata to store multiple variables.

Share Application Data

This app uses application data to share two values. To see how it works, copy and paste this code into an editor and run it.

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
When the user moves the slider, the slider_callback function calculates diffMax. Then, it uses these commands to modify the application data:

  • setappdata(hObject.Parent,'slidervalue',hObject.Value) stores the current slider value in the figure using the name, 'slidervalue'. In this case, hObject.Parent is the figure.

  • setappdata(parentfig,'difference',diffMax) stores diffMax in the figure using the name, 'difference'.

When the user clicks the push button, the button_callback function retrieves the data using these commands:

  • currentval = getappdata(hObject.Parent,'slidervalue') retrieves the current slider value from the figure. In this case, hObject.Parent is the figure.

  • diffval = getappdata(hObject.Parent,'difference') retrieve the difference value from the figure.

Create Nested Callback Functions

You can nest callback functions inside the main function of a programmatic app. When you do this, the nested callback functions share a workspace with the main function. As a result, the nested functions have access to all the UI components and variables defined in the main function. The following example code uses nested functions to share data about the slider position. To see how it works, copy and paste this code into an editor and run it.

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
The main function defines a struct array called data. When the user moves the slider, the slider_callback function updates the val and diffMax fields of the data structure. When the end user clicks the push button, the button_callback function displays the values stored in data.

Store Data Using the guidata Function

The guidata function provides a way to share data with the figure window. You can store or retrieve your data in any callback through the hObject component. This means that, unlike working with UserData or application data, you do not need access to one specific component to set or get the data. Call guidata with two input arguments to store data:

guidata(object_handle,data);
The first input, object_handle, is any UI component (typically hObject). The second input, data, is the variable to store. Every time you call guidata using two input arguments, MATLAB overwrites any previously stored data. This means you can only store one variable at a time. If you want to share multiple values, then store the data as a struct array or cell array.

To retrieve data, call guidata using one input argument and one output argument:

data = guidata(object_handle);
The component you specify to store the data does not need to be the same component that you use to retrieve it.

If your data is stored as a struct array or cell array, and you want to update one element without changing the other elements, then retrieve the data and replace it with the modified array:

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

Use guidata to Store and Share Data

To use guidata in a programmatic app, store the data with some initial values in the main function. Then you can retrieve and modify the data in any callback function.

The following code is a simple example of a programmatic app that uses guidata to share a structure containing two fields. To see how it works, copy and paste this code into an editor and run it.

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
When the user moves the slider, the slider_callback function executes these commands to retrieve and modify the stored data:

  • data = guidata(hObject) retrieves the stored data as a structure.

  • data.diffMax = maxval - data.val modifies the diffMax field in the structure.

  • guidata(hObject,data) stores the modified structure.

When the user clicks the push button, the button_callback function calls guidata to retrieve a copy of the stored structure. Then it displays the two values stored in the structure.

Related Topics