Most correct way to pass shared data between callbacks in GUIDE gui application

55 views (last 30 days)
John
John on 8 May 2015
Answered: Jan on 26 May 2017
I read the documentation for GUIDE and it suggests a couple of ways to share data between callbacks. My GUIDE application will have a figure, a bunch of GUI elements, and use global objects (i.e. I want them to be visible to all callbacks in the GUI's m file) that are initialized when the GUI is created but will be read and updated by various callbacks.
I am leaning towards using setappdata and getappdata because it seems most efficient and correct.
So suppose that upon GUI creation I instantiate an object of type vision.VideoFileReader and also an object of type vision.VideoFileWriter and store them in a struct called my_app_data, like this:
%In GUI creation function
my_app_data.videoFileReader = vision.VideoFileReader;
my_app_data.videoFileWriter = vision.VideoFileWriter;
%Setting the data into the GUI figure's handle
setappdata(handles.figure1, 'my_app_data', my_app_data);
%In another callback where I need to access the video file reader and writer
my_app_data = getappdata(handles.figure1, 'my_app_data');
%my_app_data has the video reader and writer references
Is there a better way to pass global data like those heavy objects around between callbacks?

Answers (1)

Jan
Jan on 26 May 2017
  • Do not use globals. They are a shot in your knee. As soon as you open multiple instances of your GUI or run any otehr code which uses globals with the same name, you get strange errors, which are horribly hard to debug.
  • set/getappdata is very efficient.
  • set(FigH, 'UsersData') is fine also. Use the handle of the best matching object.
  • guidata is just a wrapper for set/getappdata, which looks slightly nicer. You will never fail, if you start each callback by:
handles = guidata(hObject)
and save the handles struct, before the function is left (only required, if the handles struct was changed):
function YourCallbackXYZ(hObject, EventData, HandlesFromInput)
% HandlesFromInput: Only for compatibility with GUIDE.
handles = guidata(hObject);
handles.NewField = clock; % Any changes
guidata(hObject, handles); % Store handles in figure
AnotherCallbackABC(handles.StopButton, [], handles); % <- Function is left
handles = guidata(hObject); % handles might have changed!
handles.AnotherField = rand;
guidata(hObject, handles); % Store handles in figure
end
If you follow this strictly, you might loose some milliseconds of runtime, if you call guidata too frequently. But user interactions take seconds usually, such that saving milliseconds of runtime cannot compete with wasting minutes or hours during debugging.
I'm still not sure, if the 3rd input handles created by GUIDE is the current value taken from the figure or not. Perhaps this has changed in the past. I do not like GUIDE e.g. for this reasons. Inserting a leading handles=guidata(hObject) is possibly an overkill. But this forum contains so many corresponding threads, that suggesting a bullet proof method might be useful.

Tags

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by