Saving handles in callback function of button in dialog box opened by other button in GUI

3 views (last 30 days)
Good day all,
First of all, this is the first time I'm asking anything here, so I hope I'm making this as clear as I can. I also know there are a lot of different topics about saving the handles inside a GUI, and I've read a lot of them, but I still can't find and answer to this problem.
I have made a GUI with guide, and I have added an "option" button. This button opens a dialog box with a few uicontrols (I couldn't find a way to use guide for the dialog box as well, so I'm just coding that the hard way), most importantly 2 listboxes and 2 pushbuttons. The first listbox consists of X names, while the second box is empty to start out with. The buttons have callback function that takes the selected name, removes it from that list, and adds it to the other list. It should also save this to the handles structure of the GUI so that if you re-open the options dialog box after closing the names are still in the correct listboxes.
This doesn't work as intended, and I believe it is due to how I save the handles structures. The important parts of the code look something like this:
function varargout = MFI(varargin)
% MFI MATLAB code for MFI.fig
% Just all the standard stuff that guide automatically makes
% --- Executes on button press in adaptOptionsButton.
function adaptOptionsButton_Callback(hObject, eventdata, handles)
d = dialog('Position',[300 300 700 700],'Name','Select One');
handles.listbox1 = uicontrol('Parent',d,...
'Style','listbox', ...
'Tag', 'listbox1', ...
'Position',[75 70 100 100],...
'String', handles.parameterNames(handles.constantParameterIndex));
handles.listbox2 = uicontrol('Parent',d,...
'Style', 'listbox', ...
'Tag', 'listbox2', ...
'Position',[245 70 100 100],...
'String', handles.parameterNames(handles.fitParameterIndex));
pushbut1 = uicontrol('Parent', d, ...
'Style', 'pushbutton', ...
'Position', [195 140 30 30], ...
'String', '>', ...
'Callback', {@constantToFitButton_callback, handles});
function constantToFitButton_callback(hObject, eventdata, handles)
selectedParNum = handles.listbox1.Value;
temp_str = handles.constantParameterNames(selectedParNum);
temp_par_num = find(strcmp(handles.parameterNames, temp_str));
% Do some things that are not important for this problem, mostly just things like:
% handles.something = XYZ;
% handles.somethingelse = ABC;
guidata(handles.figure1, handles);
What happens now is that when I click the button, the dialog box appears, and the two lists are filled with the names as they are stored in the handles structure. When I select a parameter from the left list and click the "constantToFitButton" the parameter disappears from list 1, and appears in list 2, as intended. However, when I select another parameter and press the same button, this parameter gets added to the second list, but the previous selected parameter 'magically' appears back in the first list. When I close the dialog box, and re-open it, the last change I made was stored correctly and is displayed in the right listbox.
I sort of know what is going on. I believe that the handles are different in each function and that I only store them to the main GUI, so that when I press the button again, the old not-updated handles are used, and that's where everything goes amiss. I have no clue how to solve this, I have tried so many things, with so many different ways of saving handles between different functions, and with most things I do it works just fine, but with this dialog box I just keep encountering problems...
I've already tried adding "guidata(hObject, handles)" (and other variations) to the "adaptOptionsButton_Callback", but that didn't do anything.
If somebody could tell me what I'm doing wrong, I would be very grateful!

Answers (1)

Adam
Adam on 31 Jul 2017
Edited: Adam on 31 Jul 2017
Never pass handles around yourself to a callback function that you create a function handle to. Instead pass the handle of the GUI itself and use
handles = guidata( hGUI );
where you need to access the handles and
guidata( hGUI, handles )
to write an updated version of handles back to the GUI.
  4 Comments
Pascal van Beek
Pascal van Beek on 1 Aug 2017
I've tried using that, but that doesn't work quite as I expect it. I managed to get it to work, partly with your help, although I don't think it is the "correct" way to make it work. I now have this:
function bla_Callback(hObject, eventData, handles)
handles = guidata(gcf);
d = dialog(....)
listbox1 = uicontrol(...)
listbox2 = uicontrol(...)
pushbut1 = uicontrol(..., ...
'Callback', @burpButton_callback);
guidata(gcf, handles);
function burpButton_callback(hObject, eventdata, handles)
handles = guidata(gcf);
% Some random code
handles.thingIwantToStore = 42;
% More random code
guidata(gcf, handles);
guidata(handles.figure1, handles);
If I use handles.figure1 instead of gcf, then I get an empty handles structure when calling guidata(handles.figure1) inside burpButton_callback, so I needed to use gcf. But if I only used guidata(gcf, handles) within burpButton_callback, then the handles of my main GUI wouldn't be updated.
Now the guidata(gcf, handles) inside burpButton makes sure that all the list objects actually show up, and the guidata(handles.figure1, handles) makes sure that the objects actually get stored... So this cannot be the most elegant way of doing it, but at least it works.
Adam
Adam on 1 Aug 2017
Why are you still passing handles into this callback though? It doesn't do harm because you overwrite whatever it is you pass in there straight away anyway, but it adds confusion.
handles.figure1 should not have empty handles, assuming figure1 is actually the correct figure (well, if it is any GUIDE figure)

Sign in to comment.

Categories

Find more on Function Creation in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!