Problem with uiwait and uiresume

I'm trying to pass a structure from a one window to another in my GUI. To start, in the opening function, I pause the ui, using uiwait(handles.LoadWindow) (LoadWindow is the name of the child window) in order to wait for the user to input some data.
After the user does this and presses the OK button I create the structure "File" and add some fields as follows:
function OKButton_Callback(hObject, eventdata, handles)
File.Machine = get(handles.popupmenu1, 'Value');
File.Test = 'Test';
handles.output = File;
close(handles.LoadWindow);
I've added the structure to handles.output which should be returned to the main window. The child window (LoadWindow) is then closed.
At this point my understanding is that the outputFunction is automatically called:
function varargout = LoadWindow_OutputFcn(hObject, eventdata, handles)
uiresume(handles.LoadWindow)
varargout{1} = handles.output;
When I run the GUI, I get the error:
??? Attempt to reference field of non-structure array.
Error in ==> LoadWindow>LoadWindow_OutputFcn at 74
uiresume(handles.LoadWindow);
When I enter debug mode at this step my handles value is [ ]. Going back farther my handles object is fine when I press the OK button and it contains all the expected fields. It's at line 211 of gui_mainfcn.m where my handles object gets assigned the value [ ].
When I remove the uiwait/uiresume functions the code works, but it doesn't wait for the user to enter data before returning control to the main window.
I'm using Matlab r2006b on Windows 7.
Any help would be greatly appreciated.
Thanks,
Lukas

Respuestas (1)

Matt Fig
Matt Fig el 25 de Sept. de 2012
Editada: Matt Fig el 25 de Sept. de 2012
You need to update the structure with the GUIDATA function.
guidata(gcbf,handles)

11 comentarios

Lukas
Lukas el 26 de Sept. de 2012
Thanks Matt for your reply. Where exactly should I add that function? I tried adding it in the OK Callback function and in the Output function. In both cases the handle object is still [ ] when it gets to the Output function.
Matt Fig
Matt Fig el 28 de Sept. de 2012
Lukas comments:
"Matt,
I updated my handles structure at the end of the OK_button_callback with the call: guidata(handles.LoadWindow, handles)
I also added a CloseRequestFcn that gets called when I close the window. All that works, except I still have the problem with the OutputFcn I described before. I don't think that it's a problem with guidata, because the handles object is completely overwritten in gui_main.m
Any other help would be greatly appreciated.
Thanks,
Lukas"
Matt Fig
Matt Fig el 28 de Sept. de 2012
Editada: Matt Fig el 28 de Sept. de 2012
Hi Lukas, I am sorry I missed your previous comment.
So let me ask you to be a little more clear on what is going on. Say you have two GUIs, GUI1 and GUI2. GUI1 is open and you push a button which triggers GUI2 to open, correct? Then GUI2 has some uicontrols or collects some data that you want to pass back to GUI1, is this right so far?
BTW, GUI_24 (and others) demonstrates passing data between figures.
Here is a quick and dirty way to do it:
In GUI2, once the data is collected, set the userdata property of the root object to the data you want stored. Then in GUI you can simply retrieve it.
set(0,'userdata',mydata) % In GUI2
mydata = get(0,'userdata'); In GUI1
Lukas
Lukas el 28 de Sept. de 2012
Basically that's it, I want to pass data from GUI2 to GUI1. My understanding is that the function LoadWindow_OutputFcn specifies the output value for GUI2. In my case I leave the default handles.output, which I've edited to contain my data. I can then call data = LoadWindow() in GUI1 to retrieve the data.
I'll try your suggestion, but I'd still like to know why what I'm doing now isn't working; it is the way Matlab suggests you do this.
Thanks,
Lukas
Lukas
Lukas el 28 de Sept. de 2012
Yes I did try your suggestion and it works quite well. Thank you very much. I'm still puzzled as to why what I was doing before wasn't working.
Matt Fig
Matt Fig el 28 de Sept. de 2012
Editada: Matt Fig el 28 de Sept. de 2012
The OutputFcn is there to return anything you want (such as the structure containing the handles to all the GUIs objects) once the figure window is finished opening. It is not called again after that....
The more typical approach is this (for guide GUIs):
From inside GUI2, access the guidata for GUI1 by something like this:
gd = guidata(GUI1handle); % Get app data from GUI1
Now add to that structure:
gd.myGUI2data = rand; % Whatever...
% Now we store the updated structure in GUI1:
guidata(GUI1handle,gd) % Store in GUI1 appdata
Now from any callback in GUI1 we can get the data by doing:
gd = guidata(gcbf) % This will have myGUI2data in it.
Lukas
Lukas el 28 de Sept. de 2012
Editada: Lukas el 28 de Sept. de 2012
OK, I understand. I'm still a bit confused because when I enter the debugger I can see that the OutputFnc is called after the CloseRequestFnc, and that's where all the problems lie. Anyways you've shown me a couple good workarounds so I guess I should be content with that.
Thanks again,
Lukas
Matt Fig
Matt Fig el 28 de Sept. de 2012
Editada: Matt Fig el 28 de Sept. de 2012
O.k. I think I see what you were trying to do. So here is what I did. I made a GUI in guide, and set the windowstyle to modal. This GUI has one pushbutton and one editbox. Here is all of the code in the GUI (except the standard initialization code). I call it from the command line:
d = guide_modal
and it returns whatever is in the editbox. I think this is what you were trying to accomplish. Let me know:
% --- Executes just before guide_modal is made visible.
function guide_modal_OpeningFcn(hObject, eventdata, handles)
handles.output = hObject;
guidata(hObject, handles);
uiwait(handles.figure1); % stop further execution.
% --- Outputs from this function are returned to the command line.
function varargout = guide_modal_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.dat; % Set the output.
delete(handles.figure1) % delete the GUI
function edit1_Callback(hObject, eventdata, handles)
% --- Executes during object creation...
function edit1_CreateFcn(hObject, eventdata, handles)
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
handles.dat = get(handles.edit1,'string'); % Get data
guidata(handles.figure1,handles) % Save data.
uiresume(handles.figure1) % push play
Lukas
Lukas el 28 de Sept. de 2012
Yes exactly. My understanding is that it should return handles.dat in this case. When I tried running my GUI and I got to that step handles would always be [ ].
Matt Fig
Matt Fig el 28 de Sept. de 2012
So if you use code just like the above, does it work? Like I said, it works here.... Did you remember to set the windowstyle to modal in the Property inspector?
Lukas
Lukas el 1 de Oct. de 2012
I hadn't set the windowstyle to modal. I did that, but it still doesn't work. The code you posted above does in fact work for me as well. As it stands I did get my original program to work, so that's good enough for now. As a theoretical exercise however it's still of interest to me as to why my original method didn't work.
Thanks for all your help,
Lukas

Iniciar sesión para comentar.

Categorías

Más información sobre Interactive Control and Callbacks en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 25 de Sept. de 2012

Community Treasure Hunt

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

Start Hunting!

Translated by