Purpose of guihandles in programmatic Matlab GUI design - matlab

I'm working on a fairly complex (for me) GUI in Matlab, made programmatically without GUIDE.
The different but similar ways to organize GUI objects confuse me. Please tell me where my understanding is incorrect, and if they're actually different at all:
What is the functional difference between the two following handles structures:
1) A handles populated by the... handles?... of GUI objects created explicitly with a handles. prefix. The guidata function is used in Callback functions to grab an up-to-date copy of handles and then save it.
handles.button = uicontrol(...);
guidata(handles.fig,handles);
appears in handles as button.
2) A handles populated by the 'Tag' fields of GUI objects in a figure fig. This structure is created, after(?) drawing all of your GUI objects, using guihandles.
button = uicontrol(...'Parent',fig,'Tag','push'...);
handles = guihandles(fig);
appears in handles as push.
The guidata function doesn't seem to save to the handles struct made by guihandles. Is it necessary to instead use handles = guihandles(fig) at the end of every Callback?
Or am I thinking about the second type of structure wrong, and is bothering with the handles. prefix unnecessary altogether? Because creating a new GUI object and immediately entering just
guihandles
into the console shows the new GUI object listed with my old GUI objects. But I see this new object is stored openly in my Workspace, and is not under handles until I use
handles = guihandles;
again.
I apologize if it takes a re-read or two of all of the above to get what I'm asking.

There is no difference between the two handles structures that you mention. Both structures should be the same.
It is necessary to use handles=guihandles(fig); instead of guihandles by itself because you need to tell Matlab where to store the results of the guihandles function. If you do not give it a variable to store the results to on the left hand side of the equals sign, it will store your resulting structure in the ans variable.
It's not necessary to create the handles structure at the end of each callback. You should be able to use guihandles to create your handles structure only as you need it.

Related

MATLAB GUI to set Object Constructor

I'm currently designing a GUI to open a MAT file(s) to store the time-series variables in it as properties in a class, and do things to the data within the class. The Class is pretty well defined, however, it is the I/O portion of it that I need guidance on.
The constructor of the class currently is written to set the properties to empty if there are no inputs. However, I have a method that has a UIOPEN to get the file and set the properties of the class.
I have created a GUIDE GUI, where I pass the empty object of the class to the handles of the GUI and store it using guidata. The GUI has a button (along with other elements) called "Get File" that will call the property setter method when clicked to populate the properties and a listbox with those properties.
The uncertainty is in the whole architecture of what I have done. I'd like to know if there is a better way to accomplish this. It seems like it's kind of a mickey mouse way of doing it. Thanks!
I can point out a few things:
GUIDE is old, weird and it is generally better to create GUIs programmatically
once you have gotten rid of GUIDE you can have the object govern the GUI behavior easily - the object could have methods to spawn and refresh the gui, hold handles to gui elements in private properties etc.
Creating object-manged guis can also save you some problems with syncing workspace with the gui without using global, assignin or evalin. Since the object holds the data and it also governs the gui - the problem is no longer present.
Mathworks disencourages using guidata for things other than handles to graphical objects, and advices the user to use appdata

Importing values from one window to another in MATLAB GUI

Suppose that I have a button in a window that when I click on it a new window will appear. I call this window (with the name of My_New_Window) with this syntax:
My_New_Window();
I want to insert some values to this new window from main window. I know that I can use setappdata or getappdata for this purpose but Is there another way to this? For example like this syntax:
My_New_Window(Values);
Another question. When we use setappdata or getappdata, where MATLAB stores this data? In the RAM or Hard drive?
Yes, you can use My_New_Window(Values); For example, in GUIDE, whatever parameters you pass to your GUI, you can handle in the OpeningFcn using its varargin input. Simply assign varargin to your handles structure and use guidata(hObject, handles);
Regarding setappdata - according to this book the data is stored inside an "object". Since objects reside in memory, it is safe to assume that it is indeed kept in RAM.
You can store data in the GUI UserData property:
set(handletoFigure,'UserData',Values);
when you open the other GUI you retrieve the info:
Values = get(handletoFigure,'UserData);
Is there a reason why you don't want to use setappdata/getappdata?
As for your 2nd question I don't know sorry. I guess it's the RAM though

MATLAB GUI: Exchange data (handles)

I have designed a MATLAB GUI by GUIDE for image analysis. I need to share data between functions so I used the guidata function and stored it in the handles-object as it is documented (http://www.mathworks.de/de/help/matlab/ref/guidata.html).
For the auto generated callback functions (which receive handles automatically) this works well, however I also want to modify the data in self-written functions and self-written callback functions (like click on image events). I tried manually passing the handles object which gives me read access to the data but no way to store it. I tried passing the object handle too, to use guidata(hObject, handles) but the object handle does not work then.
In short: I need a way to read&write data from all functions in the file. I'm looking for a more elegant way than making everything global. That would be my last resort.
Do you have any ideas?
In GUIs, you can use the function setappdata / getappdata in order to store and share data structure between functions (link to docs).
You can use the figure as the handle. For example:
appData = struct;
appData.image = someImage;
appData.title = "someTitle";
setappdata(handles.figure1,'data',appData);
Later, you pass handles to your functions, and you can retrieve your data:
function showTitle(handles)
appData = getappdata(handles.figure1,'data');
title = appData.title;
newTitle = "someNewTitle";
appData.title = newTitle;
setappdata(handles.figure1,'data',appData);
EDIT: Just found this link, which specifies multiple strategies to share data among callbacks.
Thank you a lot! I found the error while trying to produce a reproducebable example. In my case I was using the image handle instead of the figure handle in one function because it was an image click callback and inside that function the image was redrawn so the handle wasn't valid any more.
I use gcf now to obtain the figure handle and it works fine.

Saving GUI handles in Matlab GUIDE

In Matlab GUIDE, is there any way in which I can save all my GUIhandles from a GUI.m file so that I can access these handles in a different function (a different .m file altogether, not one of the other callbacks in the GUI.m file)?
Note that I don't want to pass these handles manually to the other functions.
Since you are designing your GUI using GUIDE, any uicontrol object you put on the the current figure (e.g. GUI.fig) will have its handle added automatically to the handles structure, the variable that will be passed around between callbacks. handles is also traditionally used to pass any other program variables between callbacks by adding those variables to the handles structure and saving handles using guidata() function.
The easiest and fastest way to pass handles to external functions is to send it as an input parameter to those functions. For example, if your other external file is called auxiliary.m and contains a function called auxiliary(...), just design auxiliary(...) to accept one extra parameter called handles to receive all figure handles -- plus any other manually added variables. This is exactly the way your GUI.m works right now. Note that GUI.m looks like a single file but it's really a container for a lot of callback functions, where each one of them could be a separate .m file containing a single function of the same name. For example, if you were to cut pushbutton1_Callback(hObject, eventdata, handles) out of GUI.m and paste it in a separate pushbutton1_Callback.m file, your program works the exact same way as long as there is no duplicate files of the same name.
If you still insist on not passing the handles directly to the external function, just save the handles structure and load it in the second .m file:
% inside GUI.m
save('handles.mat', 'handles');
%inside auxiliary.m
load('handles.mat', 'handles');
I recommend the first method since there is no IO overhead and you don't need data persistence.
Use findall(figure_handle);
Example:
F=figure;
H=uicontrol('parent',F,'style','pushbutton');
uihandles=findall(F,'type','uicontrol');
If you don't have the figure handle directly, you can use
uihandles=findall(gcf,'type','uicontrol');

Using GUIDE with object-oriented MATLAB?

I have an object-oriented MATLAB app that needs a GUI, and I'd like to use GUIDE for the layout (at least). I've tried the manual way, and doing the control positioning is just too painful.
I've noticed that GUIDE is very much procedurally-oriented; it generates M-files that assume they are run from the path and aren't associated with any classes or objects.
Has anyone had experience trying to use GUIDE in an object-oriented way? If it's straightforward, I'd like to do automatic code generation as well, but I'm willing to let GUIDE just generate the .fig file and write the code myself.
When you create a gui with guide, for every button/textbox/graph etc. you put on the pane, it automatically generates the shells for the necessary callbacks, so all you have to do is fill in the code. If you change the name of the widgets (their "tags") or add or delete them, it updates your m-file for you, which is handy.
You can associate your gui with objects; the autogenerated m-file has a function outline that looks like this
function YourGUIName_OpeningFcn(hObject, eventdata, handles, varargin)
you can require that someone pass your gui an object or objects through the varargin. The canonical matlab way to do this is to pass parameter name/value pairs, so the call from the command line would look like
YourGuiName('importantobject', object1);
but you could also (especially if there is just one unique argument) assume varargin{1} is a specific parameter, varargin{2} is a second, and so on
In this case, the call from the command line would be
YourGuiName(object1);
In your openingfcn, you would then add a line like
if (length(varargin) < 1) || ~isa(varargin{1}, 'importantObjectType')
error ('you must pass an importantobject to YourGuiName, see help');
end
myimportantobject = varargin{1}
You now have a choice to make. The canonically correct way to store data in your gui is to put it in the handles structure and then store it with guidata, as in
handles.myobject = varargin{1};
guidata(hObject, handles); %this is just boilerplate
The boilerplate is necessary because, despite its name, handles does not subclass Handle, and is passed by value, not reference. the guidata command sticks handles somewhere associated with the gui figure so you can get it in subsequent callbacks.
The problem with this approach is that when you put a large object in handles, it makes the guidata command take forever. This is true even though MATLAB is not supposed to copy data when passing by value unless absolutely necessary, and it is even true if your object is a Handle, which takes like 4 bytes to pass back and forth. Don't ask me why, but I suspect it has something to do with memory management & garbage collection.
If your gui is taking a while to execute commands, and you use profile and see it hanging on the guidata command, you should just declare your object to be a global and deal with it that way
global YOURGUI_object; %it's not my fault; blame MATLAB
YOURGUI_object = varargin{1};
Then you can just have all your callbacks execute whatever method of YOURGUI_object they need.
Good luck.