How to use uicontrol and callback for a user-defined input flow?

I have being dealing with the following problem: in a GUI, user enters a number N. That creates two sets of N popupmenus. popup1 controls popup2: Let's say popup1 has options '1', '2' and '3'. If option '1' in popup1 is selected, popup2 menu should be 'A', 'B' and 'C', if '2' is selected in popup1, popup2 should be 'M', 'N' and 'P' and if option '3' is selected in popup1, popup2 should be 'X', 'Y' and 'Z'.
I have tried to use uicontrol and callback, and it creates the popups. The problem is that I don't know how to access the variables inside the popups. Does anyone know how to do this?

 Accepted Answer

In the callback of popup1, you just want to modify the string in popup2.
I guess you need something like :
function popup1_callback(hObject,eventdata,handles)
Value1 = get(handles.popup1,'Value');
if Value1==1
List = {'A';'B';'C'};
elseif Value1==2
List = {'M';'N';'P'};
else
List = {'X';'Y';'Z'};
end
set(handles.popup2,'String',List);

9 Comments

Thanks Orion, but I think my problem is when I create the popups, as the handles don't seem to be properly passed. This is the code I am running:
function pushbutton1_Callback(hObject, eventdata, handles)
handles.popup1 = uicontrol('Style', 'popup',... 'String', {'1','2','3'},... 'Position', [20 340 100 50],... 'Callback', {@popup1_callback, handles});
handles.popup2 = uicontrol('Style', 'popup',... 'String', {'A','B','C'},... 'Position', [20 300 100 50],... 'Callback', '');
guidata(hObject, handles);
function popup1_callback(hObject, eventdata, handles) Value1 = get(handles.popup1,'Value'); if Value1==1 List = {'A';'B';'C'}; elseif Value1==2 List = {'M';'N';'P'}; else List = {'X';'Y';'Z'}; end
set(handles.popup2,'String',List);
guidata(hObject, handles);
For some reason, I get an error that the handles for popup1 are not available. Do you have the same error? If not, how do you create the popups and pass the handles properly?
Are you making your gui with GUIDE ? or do you code it entirely manually ?
The code I posted supposed a gui created by GUIDE.
but I see uicontrol, so are you creating the pushbutton with guide, then the popup with uicontrol ?
it can work, but I'd say it's not optimal.
My advice :
- Create the popupmenus with GUIDE, and set the visible property to off. this way, when you open your gui, their not visible.
- in the callback of the pushbutton, instead of creating the popu, you can just now make them visible.
And for your problem, the error is normal, because when you do
handles.popup1 = uicontrol('Style', 'popup',... 'String', {'1','2','3'},... 'Position', [20 340 100 50],... 'Callback', {@popup1_callback, handles});
you are creating a new graphic object and the data passed as argument in the callback is handles. But at the moment of the creation, the field popup1 is not created yet. So in the popupcallback you defined, handles.popup1 does not exist, even if it exist and has benn stocked in the gui with guidata(hObject, handles); at the end of the pushcallback. (if you use my advcice, you will not have this problem anymore).
To fix your problem, by keeping a mix of GUIDE and uicontrol, one way is :
function pushbutton1_Callback(hObject, eventdata, handles)
handles.popup1 = uicontrol('Style', 'popup',... 'String', {'1','2','3'},... 'Position', [20 340 100 50],... 'Callback', {@popup1_callback});
handles.popup2 = uicontrol('Style', 'popup',... 'String', {'A','B','C'},... 'Position', [20 300 100 50],... 'Callback', '');
guidata(hObject, handles);
%___________________________________
function popup1_callback(hObject, eventdata)
handles = guihandles(gcf);
Value1 = get(handles.popup1,'Value');
if Value1==1
List = {'A';'B';'C'};
elseif Value1==2
List = {'M';'N';'P'};
else
List = {'X';'Y';'Z'};
end
set(handles.popup2,'String',List);
guidata(hObject, handles);
Thanks again, Orion. You are right, I am mixing GUIDE with manual coding. The reason is that I don't know beforehand how many popups the user will need. If the number of popups was fixed, I would definately use only GUIDE, but I don't know how to do it if the number of popups is only defined at runtime. If you would have a solution that you think is optimal, please let me know. Or else I will just use your last suggestion. Thanks again.
If the number of popup is unknown, then you're indeed gonna have to use uicontrol. GUIDE is more used for a defined number of objects in a figure.
Note : when I said not optimal, I just meant that debbuging a "mixed" gui (guide + control) can be difficult, especially if you're not used to making guis. Otherwise, it a totally valid way to make guis, I do it myself.
Hello Orion, If I copy and paste your code, I still get the same error:
Reference to non-existent field 'popup1'.
Error in test>popup1_callback (line 91) Value1 = get(handles.popup1,'Value');
Error while evaluating uicontrol Callback
Did it run for you?
change
guidata(hObject, handles);
by
guidata(gcf, handles);
I copy/pasted a wrong line in the previous/previous code.
I pasted
function popup1_callback(hObject, eventdata)
handles = guihandles(gcf);
instead of
function popup1_callback(hObject, eventdata)
handles = guidata(gcf);
this works

Sign in to comment.

More Answers (1)

Or use this framework where you can just plug your code into the callbacks for various sliders, listboxes, etc. http://www.mathworks.com/matlabcentral/fileexchange/24224

1 Comment

Hello Image Analyst, Thanks for your reply. If i understand it correctly, in all examples you sent the objects are defined before runtime, which would make my life a lot easier. The problem I have is that the popups will have to be created at runtime and I am struggling to access the handles in this case. Would you have an example where user enters N, two sets of N popups are created and popup1 controls popup2?

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Asked:

on 22 Nov 2014

Commented:

on 23 Nov 2014

Community Treasure Hunt

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

Start Hunting!