I have a listbox(tag:listbox) that gives different choices of plotting(axes tag:plotty), and a pushbutton(tag: NextButton) called "next" which execute the choice that the listbox made. My code in GUI looks something like this:
%some code
handles.i = 1;
handles.k = length(files);
handles.files = files;
guidata(hObject, handles);
% --- Executes on selection change in plotbox.
function listbox_Callback(hObject, eventdata, handles)
files = handles.files;
i=handles.i;
axes(handles.plotty);
listbox_index=get(hObject, 'Value');
switch listbox_index
case 1
[data,~,~] = xlsread(files{i});
x = 1:6;
plot(x, data(1:end))
case 2
[data,~,~] = xlsread(files{i});
x = 2:7;
plot(x, data(1:end))
case 3
[data,~,~] = xlsread(files{i});
x = 4:9;
plot(x, data(1:end))
end
% --- Executes on button press in NextButton.
function NextButton_Callback(hObject, eventdata, handles)
%some code
guidata(hObject, handles)
After some fig test run, the GUI is able to run but not correctly---it seems that my listbox function and pushbutton works separately.
No matter which choice I made in the listbox. The pushbutton automatically execute whats in listbox function case 1, and never goes to case 2 and 3.
I would like to fix the code, any clue is appreciated. Thank you!!

 Akzeptierte Antwort

Adam
Adam am 29 Jul. 2016

1 Stimme

You should never call one uicontrol's callback from inside another one and certainly not passing down the hObject of the first one.
Your listbox callback is actually getting called on the pushbutton object (the 'hObject' that was passed in) whose value will never change.
Why do you have a listbox callback and a button that will also trigger the same functionality? Do you want the callback to trigger when the listbox changes even if you don't press the button?
If not you should have the main piece of code in your pushbutton callback and you should refer to the listbox by its tag as:
get( handles.listbox, 'Value' )

5 Kommentare

chlor thanks
chlor thanks am 29 Jul. 2016
Bearbeitet: chlor thanks am 29 Jul. 2016
Thank you Adam! I am not very clear on matlab GUI logic, thus I called the listbox from pushbutton as I intend to
step 1: allow user to make a choice in listbox (i.e. case 4 (default plot 1))
step 2: pass the listbox choice to pushbutton (i.e. case 4 plot 1--> case 4 plot 2-->case 4 plot 3-->etc.)
So whenever the pushbutton is pressed, it only executes within the choice listbox gets from user. In my understanding, do you mean that my pushbutton callback actually overrides the listbox callback since they are both unicontrols?
I tried the get() command and it seems like my listbox is overriding pushbutton now as the plot stays to be "plot 1". How can I best coordinate the two together?
Adam
Adam am 29 Jul. 2016
From what you are saying you don't need a listbox callback at all. You only need a callback if you actually want something to happen when the user changes that control. In your case I don't think you do want that as the user must press the button before anything happens.
So, the code that is in your listbox callback should be in your pushbutton callback instead, though getting the listbox as I showed above, not by using hObject.
Callbacks will never 'override' each other, but they are meant to be called by the GUI itself which will pass the relevant parameters to the callback for especially hObject.
Syntactically you can call the callbacks yourself, but in your case you passed the wrong uicontrol handle to the callback so the listbox callback operated on the pushbutton when called from the pushbutton.
If you want code in a callback to be called from multiple places then you just factor it out, pulling the relevant bits out of the specific UI component in its callback and then passing these to a shared function that acts on data, not on UI components - that data may be taken from an edit box or a slider or listbox or just hard-coded, it doesn't matter for the function.
chlor thanks
chlor thanks am 29 Jul. 2016
Bearbeitet: chlor thanks am 1 Aug. 2016
Hi Adam, I read your comment several times however I am still a bit confused on your last paragraph, can you maybe do a simple example of how it works?
I am confused as to how to build a shared function that is used by different callbacks, and I am having difficulty doing so especially when the only common connection between my listbox and pushbutton is axes(handles.plotty), everything else is not shared in anyway at all.
As for the current solution (pull the code from my listbox callback to the pushbutton callback), the plot works nicely when I press the button, but I do wish to set a default plot when the user makes a choice in listbox. Also, I have noticed that my nextbutton works very inconsistently as well, the current out of total plots doesn't display the correct index, and when I press the previous button, a new plot is displayed that looks nothing like the previous plot I just viewed.
Ideally I wish to be able to:
  • when user's choice is first made in listbox on case 4, it displays case 4 default plot 1;
  • when user is viewing case 3 plot 3, and then makes a listbox choice on case 5, plot will display case 5 plot 3.
Would you able to give me a little more hints on achieving so? I appreciate your comments as always!
Adam
Adam am 1 Aug. 2016
Well, the general idea is that if you want to do the same thing under a listbox callback and a pushbutton callback then you want that code somewhere that you can call from either. Then in the callbacks themselves you have to deal with getting the information you need.
In the listbox callback this may be just the listbox value, in the pushbutton callback it may be still the listbox value, but also the whatever information it is that your button wants to do differently from just using the listbox callback.
In your case I assume that the information you get from the pushbutton is the plot number, to go with the case number retrieved from the listbox.
When you trigger the functionality from the listbox you presumably still need to get the plot number from somewhere though - e.g.
listboxCallback(...)
listbox_index = get( hObject, 'Value' )
plotIdx = handles.i;
runCommonCode( handles.plotty, listbox_index, plotIdx )
pushbuttonCallback(...)
listbox_index = get( handles.listbox, 'Value' );
plotIdx = someLogicForNext(...);
runCommonCode( handles.plotty, listbox_index, plotIdx )
chlor thanks
chlor thanks am 1 Aug. 2016
This works! Thank you sir :D

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Data Import and Analysis finden Sie in Hilfe-Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by