Using save(Filename) in a Callbackfunction of a button

I am programming a GUI and i want to save data in a callback function in matfile. I was under the impression, that if i use save only the functions workspace will be saved. Does hObject include all GUI objects in the function workspace?
save_pushbutton = uicontrol('Parent', tab ,'Style','pushbutton','Callback',@save_callback,...
'String','Save',...
'FontSize',8,...
'Units', 'normalized', 'Position',[.15 .05 .1 .05]);
editfield = uicontrol('Parent', tab ,'Style','edit','Callback',@input_control,...
'String','',...
'FontSize',8, 'TooltipString', ['Input must be numerical'], ...
'Units', 'normalized', 'Position',[.15 .8 .1 .05]);
function save_callback(hObject, eventdata)
x = get(editfield,'String');
save('save.mat');
end
In this example i want to save x in the mat file. Since i have a lot of variables i tried to keep it short and not name them all individually (save(Filename,x,y...).
Edit: Apparently there is a GUI workspace and GUI/callback workspace. I only want to save the GUI/callback.
Edit: Added more code

 Accepted Answer

"I was under the impression, that if i use save only the functions workspace will be saved."
Yep, as confirmed by,
help save
save Save workspace variables to file.
save(FILENAME) stores all variables from the current workspace in a
MATLAB formatted binary file (MAT-file) called FILENAME
"Does hObject include all GUI objects in the function workspace?"
No. hObject, which is the handle to the GUI object that contains the save_callback() callback function.
Your save() funciton call should do what you're describing. It should save all variables in the save_callback() workspace that come prior to save(). If you're just trying to save the variable x,
save('filename.mat', 'x');

5 Comments

As i edited in the Question there is the GUI workspace and the GUI/callback workspace.
Using whos resulted in listing both workspaces.
using the save comman results in a mat file with both Data from both workspaces.
i.e.:
function save_callback(hObject, eventdata)
x = get(Editfield,'String');
save('save.mat');
end
save.mat includes now my Editfield.
If save_callback is a nested function within your main gui, then its workspace will also include the parent function workspace. If it's standalone function or a local function then its workspace only contains the variables defined within the function.
If you don't need the callback to be a nested function (i.e. doesn't use variables from the parent workspace directly) then convert it to a local function (move it out of the body of the main gui function).
Continuing Guillaume's point, if nesting is not needed, un-nest the function and your problem is solved.
If nesting is needed and you only want variables created in the nested function, you could record all variable names at the very beginning of the function and then at the end before you save and detect which variables were added within the nested funciton. That would look like this.
function save_callback(hObject, eventdata)
vars1 = who; %list all vars in workspace at beginning
x = get(editfield,'String');
vars2 = who; %list all vars prior to save
saveidx = ~ismember(vars2, vars1); %index of *new* vars to save
vars2save = vars2(saveidx); %list of variable names to save
save('save.mat', vars2save{:});
end
Since i use get(editfield,'string') i think i need the function to be nested.
I will try out your solution @Adam thanks a lot!
Since hObject will be a handle to the caller, you can get the figure handle from it (if i|hObject| is not the figure, it will be one of its ancestors). From the figure, you can get a handle to any of its children including the edit control. So you don't have to use nesting for that.
You can also simply change your callback signature so editfield is an input and pass that as part of the callback arguments.
But, since saving whatever happens to be in the workspace is rarely a good design, what I'd suggest you do instead is make all the variables you want to save fields of a single structure and save just that structure with the -struct option to make these fields actual variables in the mat file:
function save_callback(~, ~)
varstosave.x = get(editfield, 'String');
varstosave.y = [1 2 3 4 5];
somevarnottobesaved = [6 7 8 9 10];
save('save.mat', '-struct', varstosave);
end
which gives you full control over what you're saving without having to specify the list in the call to save.

Sign in to comment.

More Answers (1)

Luna
Luna on 20 Nov 2018
Edited: Luna on 20 Nov 2018
"Does hObject include all GUI objects in the function workspace?"
According to that, if you define all of your uicontrol elements under a property of your main gui class structure, hObject includes all items.
Actually first input of your callback is an instance of your main gui class object.
If you store uicontrol elements in a class property you can reach them everywhere.
For ex:
classdef myClass < handle
properties
guiHandles
someVariables
end
methods
% Constructor method
function myclass(obj)
obj.someVariables = {'bla bla'};
end
function createGUI(obj)
obj.guiHandles.mainFig = figure; %% creates a figure
obj.guiHandles.pushbutton = uicontrol(... %% creates a pushbutton inside that figure
'Parent',obj.guiHandles.mainFig,...
'Callback', @obj.pushbtnCallback,...
'String','OK',...
'units','normalized',...
'Position', [0.5 0.5 0.3 0.3]...
);
end
function pushbtnCallback(varargin) % Callback of the push button
% you can see each gui item which are stored in the guiHandles
% property of the class object. You can create any uicontrol
% element
myclassObjHandle = varargin{1}; % hObject -> main GUI object
pushbuttonObjHandle = varargin{2}; % source -> source object of this callback
eventData = varargin{3}; % eventData -> event data of the pushing button action
% you can save myclassObjHandle in here or you can choose to save it in command window or your script where you have called createGUI function.
end
end
end
To create myClass obj and its GUI call like below in your command window or in another script or function:
obj = myClass
obj.createGUI
% Do not forget to put debug point to pushbtnCallback function 1st line and then you will see what's inside the myclassObjHandle.guiHandles structure
% if you save obj in here it includes all gui items. It is the same object with myclassObjHandle.

1 Comment

Luna
Luna on 20 Nov 2018
Edited: Luna on 20 Nov 2018
Also you can read more about handle classes to learn usage:

Sign in to comment.

Tags

Asked:

on 20 Nov 2018

Commented:

on 21 Nov 2018

Community Treasure Hunt

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

Start Hunting!