MATLAB: Opening Another Figure Doesn’t Create Handles in GUIDE. How to fix it

figguiguide

I have a main figure im1.fig. On clicking a pushbutton, it opens up im2.fig. When I try to use handles through this method to access content of edit text boxes, it gives error "Struct contents reference from a non-struct array object handles matlab". However, when I use GUIDE editor to run im2.fig, everything works perfectly fine.
Till now, I understand that the handles are not created when you directly access a .fig file instead of running it using GUIDE Editor, but I need these handles to be created by opening .fig file directly. How can this be achieved?

Best Answer

"I need these handles to be created by opening .fig file directly. How can this be achieved?"
That will never happen automatically when you use openfig('Filename.fig) or open('Filename.fig')
The handles structure is created as a side effect of the call to gui_mainfcn() . That call is at the end of the "Begin initialization code - DO NOT EDIT" section of the first function in the .m that corresponds to the .fig file -- so the handles structure is not created and stored against the figure unless the .m file is executed.
In turn, gui_mainfcn() calls guihandles() with the figure handle to create the handles structure, and then uses guidata() to store the resulting structure attached to the figure.
The handles structure is stored against a particular figure. When GUIDE creates a callback to a routine, the figure that it accesses to try to locate the handles structure is the figure to which the object being invoked belongs. For example, for the Callback for the radio button with the tag 'centrifugal_fan', GUIDE will set the Callback property of the radio button to
@(hObject,eventdata) noise_fan2('centrifugal_fan_Callback', hObject, eventdata, guidata(hObject))
This is an anonymous function that will be invoked with the standard callback arguments of the radio button object itself, and some event-specific data, and the anonymous function calls into the .m file, passing in the object (the radio button) and the event data, and the guidata retrieved relative to the radio button object itself -- which is to say, the handles subset that is stored against the figure that the button is part of.
The handles structure used is not some kind of handles structure of a "project", or of a "GUI": it is the handles structure attached to that one figure. And that in turn means that if you use GUIDE to in any way create or open or manipulate multiple figures, each of the figures will have independent handles structure... provided that a handles structure was initialized for the figure at all. If no handles structure was initialized for the figure, then the code will crash with exactly the error you are seeing, about struct reference to a non-struct object.
Thus, if you are going to openfig() to bring in a new figure file, then you need to work it like this:
fig2 = openfig('AppropriateFigFileName.fig');
handles2 = guihandles(fig2);
guidata(fig2, handles2);
and then you can access handles on the second figure.
Notice that when you do this, that the original handles structure and the second handles structure do not know about each other. If, for example, the new figure brought in... say, a pushbutton named ChooseGearRatio, then handles.ChooseGearRatio will not work to access it. The callbacks will not be able to refer to the other figure -- not unless you specifically program them to know about each other.
For example, you could:
mainfig = gcf; %the figure handle of the existing gui
fig2 = openfig('AppropriateFigFileName.fig');
handles.fig2 = fig2;
guidata(mainfig, handles); %refer to the new figure in the current handles
handles2 = guihandles(fig2);
handles2.mainfig = mainfig; %refer to the original figure in handles2
guidata(fig2, handles2);
Then the old figure would be able to use
handles.fig2.ChooseGearRatio
to refer to the ChooseGearRatio object in the other figure, and the new figure would be able to use handles.mainfig.whatever to refer to what the first figure knows as handles.whatever
Related Question