Matlab jumps over my if-statement in my GUI even if the value is true?
Show older comments
Below is the snippet of the code. I was debugging and saw that the value for 'n' was 3 and 'm' was 1, thus it entered the initial if-statement. However, after executing the 2nd line it goes to the "if m==1" and instead of executing it (since it is true) it just skips to the second end. This is within my push-button callback.
n=getappdata(0,'n'); m=getappdata(0,'m');
if n>=1
cvList((n+1):12)=0;
if m==1
mList(2:12)=0;
elseif m==0
mList((n+1):12)=0;
end
end
11 Comments
Fangjun Jiang
on 30 Jul 2018
what is the data type of m (i.e. class(m))? Might it be the issue of floating point data comparison? For example, the value of m is 1.00000001?
Image Analyst
on 30 Jul 2018
Building on Fangjun's reply...Maybe try
m = round(getappdata(0,'m'));
MechE1
on 30 Jul 2018
Adam
on 31 Jul 2018
'randomly ignore' suggests that sometimes they are ignored and sometimes the code goes into that block, but with no logic as to which it is. This seems highly unlikely!
Dennis
on 31 Jul 2018
Can you append the .fig aswell i am having trouble to reproduce your error.
Meanwhile 2 things:
- There is always a better way than naming variables CV1, CV2, CV3.... you can avoid alot of trouble and alot of work if you index them (CV(1), CV(2), CV(3)). For more details on this topic please have a look at Stephen's tutorial https://de.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval
- You use setappdata to store alot of values to Matlab root - thats why your gui 'remembers' some values (e.g. all stored at root). A better solution might be to use your figure or another object to store your data. Even guidata could be a neat way of handling this.
Your code is far too complex, because of all of that copy-and-pasting and repeating the same things over again. Computers are really only good at one thing: doing simple operations quickly in a loop: this means any time you copy-and-paste code, you are just doing the computer's job for it! Copy-and-pasting code is a sign that you are doing something wrong. Learn to use arrays. Rather than all this:
set(handles.CV2,'Visible','on'); set(handles.CV3,'Visible','on'); set(handles.CV4,'Visible','on'); set(handles.CV5,'Visible','on'); set(handles.CV6,'Visible','on'); set(handles.CV7,'Visible','on'); set(handles.CV8,'Visible','on');
set(handles.CV9,'Visible','on'); set(handles.CV10,'Visible','on'); set(handles.CV11,'Visible','on');
put them into one handles array and then you can just call this:
set(handles.CV,'Visible','on');
Guillaume
on 31 Jul 2018
Matlab jumps over my if-statement in my GUI even if the value is true
if the if is not executed there can only be one reason: despite what you think the value isn't true
Two commons reason why if doesn't behave the way you expect
- m is very close to, but not exactly 1. See for example:
m = 1 + 1e-12 %will display as 1 on the command line
m == 1 %will return false
- m is a vector
m = [1 0];
if m
disp('true'); %won't be displayed
end
Do you always edit each value of each CV MOPD field when you run your programm?
If not the callbacks of your edit fields won't get executed. The values then might appear random because some of them might been stored and retrieved from root of an earlier run.
A small example how to create a few edit boxes and change their visibility:
handles.fig=figure('position',[200 400 800 600]);
for i=1:12
handles.CV(i)=uicontrol('style','edit','string','0','position',[80 40+40*i 100 20],'visible','off'); %creating edit boxes and assigning handles
end
pause(2)
set(handles.CV,'callback',{@mycb,handles})
set(handles.CV,'visible','on') %change all edit boxes
function mycb(hObject,~,handles) %1 callback to rule them all =P
myvalue=getappdata(handles.fig,'myvalue'); %data stored at handles.fig rather than root
if isempty(myvalue)
myvalue.CV=zeros(12,1); %data stored as 1 structure instead of dozens of variables
end
for i=1:12
if hObject == handles.CV(i) %check which edit box issued the callback
myvalue.CV(i)=str2double(get(hObject,'String'))
end
end
setappdata(handles.fig,'myvalue',myvalue)
myvalue.CV
end
"How exactly can I access all the objects at the same time?"
Commands set and get work with arrays of handles so you don't need to do anything special, e.g. to set all objects in array A to invisible:
set(A,'Visible','off')
You can even set different values for an array of handles, so they don't all need to use the same value: read the documentation carefully to know how, and experiment!
"I understand I can place their values as such:"
handles.CV{1}=get(hObject,'Value');
"But how can I store them in array format to access their visibility? Since they are all different edit boxes?"
The handles should be stored in an array. This is easy using indexing (e.g. creating the boxes in a loop) or all at once (many graphics commands can create multiple objects at once, and return an array of handles). The fact that they are different edit boxes is irrelevant. If the boxes are arranged systematically then they could easily call the same callback with an extra argument (e.g. the loop counter) and then the callback function knows which button was pressed or the counter can be used as an index. See some of my FEX submissions for examples of this:
Answers (1)
Matlab is case-sensitive: If, Else, End, Setappdata, Isempty will not work - use if, else, end, setappdata, isempty instead.
Categories
Find more on Creating, Deleting, and Querying Graphics Objects 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!