For Loop within Matlab GUIDE - matlab

I have Matlab GUI that uses push button that executes certain code.
all of that works, except that when code reaches for loop, execution does not seem to enter that.
1) Any idea how for loop is implemented within framework of Matlab GUIDE code?
2) is there a way to debug GUI code ( only way I could was trough 'disp' statements,) using breakpoints, as when I run the GUI, breakpoints get removed.
after having read the solutions, I found that
(1) happened because the for loop index was not changing as length of array
that I was indexing on, was not changing. I explain this in the code.
(2) My bad, I was putting breakpoints before running the GUI, when I did the other way around, it breaks fine.
% Opening func
function Regression_OpeningFcn(hObject, ~, handles, varargin)
NoiseMin = -12;
NoiseMax = 10;
NoiseRes = 2;
handles.noiseMin = NoiseMin;
handles.noiseMax = NoiseMax;
handles.noiseRes = NoiseRes;
%**this executed when value changed in edit text box***
function noiseMinDbEditText_Callback(~, ~, handles)
handles.noiseMin = str2num(get(handles.noiseMinDbEditText,'String'));
% When GUI is running, following shows change from -12 sucessfully
disp(strcat('Noise Min = ',num2str(handles.noiseMin)));
function noiseMinDbEditText_CreateFcn(hObject, ~, ~)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%Similar code for noiseMax and noiseRes(not shown here)
`% Here, code enters the Pushbutton callback
function StartRegressionPushButton_Callback(~, ~, handles)
snr_res = handles.noiseRes;
% here, snr_vecs still shows [-12 2 10]
snr_vecs = [handles.noiseMin:handles.noiseRes:handles.noiseMax];
So, basically, when GUI runs, entering and changing the values in text box corresponding to min, max and res snr variables shows me the change, but as soon as I enter the pushbutton dialog box, the changed values( that were captured in global variable "handles") do not show up as I break in the code there.
Any help with this? [for loop problem arose as I was indexing based on snr_vecs array, which is not changing, and so for loop was executing,but not as it should be]
sedy

Using Matlab guide
Guide is basically only a tool to create fig. files. All you can do with guide you could do yourself programmatically. Creating ui-elements works by hand just as easy as with guide (I actually prefere creating gui elements programmatically, since I think guide is very poorly coded)...
Every guide-elements has its callbacks which have to be coded somewhere, usually (I think 100% of the time) the fig file has the same name as the .m file. Find the corresponding .m-file and go to the callback you are interessted in. There you can place breakpoints just as easy as in any other piece of code.
Note: you can even change the code without having to reopen the fig file!
For loops or anything that works in regular code works for ui-element code.

The reason for handles not getting updated was missing following statement at end of function callback whose variable needs to be used in other callback.
guidata(hObject,handles);
I fixed that and it works nicely.
sedy

Related

live updating edit field when slider value is changing

I have a slider and a edit field, which are defined as
uicontrol(fig,'Style','Slider','Units','characters','Position',[17.1+f*iwidth 10.5 4 28.6],'Min',0,'Max',1000,'Value',500,'SliderStep', [1/500 , 10/500 ],'Callback','evaluation_callbacks(''results'',guidata(gcbo))','Tag',['slider' int2str(f)]);
uicontrol(fig,'Style','Edit','Enable','inactive','Units','characters','Position',[14+f*iwidth 8.2 9 1.6],'FontSize',10,'String',500,'Tag',['rating' int2str(f)]);
With the following Callback functions:
function evaluation_callbacks(varargin)
% EVALUATION_CALLBACKS Callback functions for the evaluation interface
%
% evaluation_callbacks(fname,varargin) executes the callback function
% fname_callback with various parameters
fname=[varargin{1},'_callback'];
feval(fname,varargin{2:end});
%%%saving the rating results and proceeding to the next experiment or exiting
function results_callback(handles)
% stop audio
clear sound
%getting the ratings for all files
for f=1:handles.nbfile
handles.ratings(handles.expe_order(handles.expe),handles.file_order(f))=get(getfield(handles,['slider' int2str(f)]),'Value');
end
%saving the whole results (to avoid losing data if the program terminates early)
results='';
fid=fopen(handles.resultfile,'w');
for e=1:handles.nbexpe
for f=1:handles.nbfile
fprintf(fid,'%d\n',handles.ratings(e,f));
end
end
fclose(fid);
if handles.expe<handles.nbexpe
handles.expe=handles.expe+1;
% updating title
set(handles.experiment,'String',handles.parameter{handles.expe});
% update evaluation parameters
set(handles.scale90,'String',handles.high{handles.expe});
set(handles.scale10,'String',handles.low{handles.expe});
if handles.expe==handles.nbexpe
pos=get(handles.results,'Position');
pos(1)=pos(1)+2.5;
pos(3)=19;
set(handles.results,'Position',pos,'String','Save and exit');
end
%moving all the sliders back to 50
for f=1:handles.nbfile
shandle=getfield(handles,['slider' int2str(f)]);
set(shandle,'Value',500);
rhandle=getfield(handles,['rating' int2str(f)]);
set(rhandle,'String',500);
end
%randomizing the order of the tested files for the next experiment
handles.file_order=randperm(handles.nbfile);
%testing whether a break is needed before the next experiment
if etime(clock,handles.time) > 20*60
wfig=warndlg(['You have been working for ' int2str(round(etime(clock,handles.time)/60)) 'minutes. It is recommended that you take a break of at least the same duration before starting the next experiment. Click on OK when you are ready.'],'Warning');
uiwait(wfig);
end
handles.time=clock;
% Start next audio sample
play_callback(handles,1)
guidata(gcbf,handles);
else
%exiting
close(gcbf);
end
%%%rounding and displaying the values of the sliders
function slider_callback(handles,f)
shandle=getfield(handles,['slider' int2str(f)]);
set(shandle,'Value',round(get(shandle,'Value')));
rhandle=getfield(handles,['rating' int2str(f)]);
set(rhandle,'String',get(shandle,'Value'));
As it is right now, the edit field value are not live updated if. The value of the edit field are only updated if the slider is moved and the mouse button is released.
I have tried to add a listener to the slider, but I cannot make it work. So far I have followed the following guides/posts without any luck.
http://undocumentedmatlab.com/blog/continuous-slider-callback
and
https://se.mathworks.com/matlabcentral/answers/140706-use-slider-for-live-updating-of-threshold-on-2d-contour-plot
Can anybody help?
Add a listener in the myGUI_OpeningFcn. Note you need to change myGUI to match your GUI script filename.
addlistener(handles.slider1,'ContinuousValueChange',#(hObject,eventdata)myGUI('updateText',hObject,eventdata,guidata(hObject)));
Then, add the following function in your GUI script.
function updateText(hObject, eventdata, handles)
set(handles.text2,'String',get(hObject,'Value'));
guidata(hObject,handles);
More specifically, in your case, you need to add a bunch of listeners:
for i=1:handles.nbfile
addlistener(getfield(handles,['slider' int2str(i)]),'ContinuousValueChange',#(hObject,eventdata)myGUI('updateText',hObject,eventdata,guidata(hObject)));
end
Then add:
function updateText(hObject, eventdata, handles)
f = hObject.Tag(7:end);
set(getfield(handles,['rating' f]),'String',get(hObject,'Value'));
guidata(hObject,handles);
Update
In your GUI script, add listeners in the OpeningFcn (which is the second function automatically generated by Matlab when your GUI was created):
for i=1:handles.nbfile
addlistener(getfield(handles,['slider' int2str(i)]),'ContinuousValueChange',#(hObject,eventdata)myCallBackFileName('updateText',hObject,eventdata,guidata(hObject)));
You will need to change myCallBackFileName to match the filename of your callback script. Then add the updateText function.

How to disable the progress bar when using the nlfilter function in Matlab?

Each time I call the nlfilter function a progress bar window appears. How could I disable that window?. Is there an option like -q?
I'm processing an image by rows and applying a custom function, so the window generated when calling to the nlfilter function is bothering quite a lot and also decreasing the performance of my system.
Note that I'm only want disable the window momentarily.
The waitbar within MATLAB definitely reduces the performance of your code as well as gets really obnoxious when running long-running tasks on some operating systems as it can steal the focus of your keyboard/mouse randomly.
I personally create my own waitbar function and place it on the MATLAB path so that it is evaluated rather than the built-in.
I have a more complicated text-based progress bar, but the following function will simply print the messages to the command line. You could even remove the first block and have the contents simply be varargout = {[]}; and you will have no output.
function varargout = waitbar(varargin)
if nargin >= 2 && ischar(varargin{2})
disp(varargin{2})
elseif nargin >= 3 && ischar(varargin{3})
disp(varargin{3})
end
varargout = {[]};
end
Be sure to save this in waitbar.m somewhere high on your MATLAB path.
NOTE: This will silence all waitbars so if you want to restore the typical waitbar behavior, you will want to remove/rename this file.

Multiple varargout matlab error

I have created a multiwindow GUI and have been confused with such a problem for a while:
I've got main GUI window with two buttons which are leading to two another GUI windows. One does not have an output_fcn options and closing normally, but another GUI window has 4 output arguments, which I use in subwindow and the problem is:
Attempt to reference field of non-structure array.
when i'm trying to close the window.
Here some code:
function varargout = changeme_dialog1_OutputFcn(hObject, eventdata, handles)
varargout{1} = get(handles.varP1,'String');
varargout{2} = get(handles.varP2,'String');
varargout{3} = get(handles.varP3,'String');
varargout{4} = get(handles.varP4,'String');
An error first appears in the varargout{1}.
What's the problem?
I ran into this problem several years ago, and am quite surprised if this turns out to be the same issue. The thing is, by the time OutputFcn is called, the handles structure was already deleted\cleared, for this reason you are getting an error because you're trying to reference something that MATLAB doesn't even recognize as a struct.
What I did was storing the outputs in appdata and retrieving them during OutputFcn (note: nothing's stopping you from retrieving the data in the calling code, but if you respect scope this is a more "correct" way to go about it IMO):
Step 1: Save outputs to appdata upon clicking a "close window" button:
function pushbutton1_Callback(hObject, eventdata, handles)
setappdata(0,'Output',{...
[handles.Hor1 handles.Ver1], [handles.Hor2 handles.Ver2]...
[handles.Hor3 handles.Ver3], [handles.Hor4 handles.Ver4]...
})
delete(handles.figure1); %// This actually initiates figure removal
(Here Hor1 ... Ver4 are just some example fields in handles.. In your case it would be get(handles.varP1,'String'); etc.)
Step 2: Retreive outputs from appdata, clearing it afterwards
function varargout = changeme_dialog1_OutputFcn(hObject, eventdata, handles)
...
varargout{1}=getappdata(0,'Output'); %// <== Wizardry Part 2
rmappdata(0,'Output') ;
...
I hope this helps or at least points you in the right direction.

Showing data on Matlab GUI which is continuously being updated in a separate Matlab function

I have a function in Matlab which is getting continuous sensor values from a hardware. It gives a flag when new values are available and we can update the variables holding these values. Following is a dummy function to mimic what this function is doing.
function example( )
% Example function to describe functionality of NatNetOptiTrack
% Hardware initialization,
% Retriving real time information continuously
for i = 1:100 %in real time this loop runs for ever
data = rand(3,6);
% Send the updated data to gui in each iteration
end
end
i have made a gui using guide as shown in the figure:
So the data to be displayed is a 3x6 matrix with columns corresponding to X Y Z Roll Pitch and Yaw values while rows correspond to Objects.
I want to show the continuously updated values from this function on the gui. Is there a way i can initialize gui inside my example function and update the output value by using the handles inside my loop. I tried copying the gui code inside the example function as a script, it was able to initialize but was not recognizing the handles.
Also i want to show the current values on command window when i press the button.
Thanks
If you launch the GUI and then run the function, you should be able to get the handles to the controls on the GUI provided that you make the GUI figure handle visible and set its tag/name to something appropriate. In GUIDE, open the Property Inspector for the GUI and set the HandleVisibility property to on, and the Tag property to MyGui (or some other name). Then in your example.m file do the following
function example( )
% Example function to describe functionality of NatNetOptiTrack
% get the handle of the GUI
hGui = findobj('Tag','MyGui');
if ~isempty(hGui)
% get the handles to the controls of the GUI
handles = guidata(hGui);
else
handles = [];
end
% Hardware initialization,
% Retriving real time information continuously
for i = 1:100 %in real time this loop runs for ever
data = rand(3,6);
% update the GUI controls
if ~isempty(handles)
% update the controls
% set(handles.yaw,…);
% etc.
end
% make sure that the GUI is refreshed with new content
drawnow();
end
end
An alternative is to copy the example function code into your GUI - the hardware initializations could occur in the _OpeningFcn of your GUI and you could create a (periodic) timer to communicate with the hardware and get the data to display on the GUI.
As for displaying the current data when pressing the GUI button, you can easily do this by writing the contents of the GUI controls to the command line/window with fprintf. You will though need to make your example function interruptible so that the push button can interrupt that continuously running loop. You can do this by either adding a pause call (for a certain number of milliseconds) that gets executed at the end of each iteration of your loop, or just make use of the drawnow call from above (that is why I placed it outside of the if statement - so that it will be called on each iteration of your loop.
Try the above and see what happens!

the push button in matlab exe file doesn't work

I developed a Matlab GUI program which it has four editbox & one pushbutton; my application works properly when I run it with Matlab software, but after converting it to exe file (standalone), the pushbutton doesn't work, means it doesn't show the output in 'Result' editbox. so what's the problem?
here is my pushbutton code:
function btnCal_Callback(hObject, eventdata, handles)
a=str2num(get(handles.txbLow,'string'));
b=str2num(get(handles.txbHi,'string'));
f=get(handles.txbForm,'string');
x=0.5*((b-a)*(-1*(3/5)^0.5)+b+a);
g=subs(f,'x',x);
sum=(g)*(5/9);
x=0.5*(b+a);
g=subs(f,'x',x);
sum=sum+(g)*(8/9);
x=.5*((b-a)*((3/5)^.5)+b+a);
g=subs(f,'x',x);
sum=sum+g*(5/9);
result=sum*((b-a)/2);
set(handles.txbResult,'string',result);
First, I'm a bit confused with
result=sum*((b-a)/2); % "result" is numeric
set(handles.txbResult,'string',result); % "result" should be string
Next, just as a hint. To "debug" your deployed code, try to launch your exe from cmd, in this case, you would see some messages there, and they might help.
your 'result' needs to be either double, char, or cell. You can do this by e.g.
set(handles.txbResult,'String',char(result);
However: I got exactly the same problem with a very similar code on my Mac. The Application runs very well if executed via "run" in Matlab, but once I compiled it to a standalone.app one hears this error-sound when pushing the button, nothing else is happening.
Trying to set the 'result' variable as "global" helped solving this problem for another program that I wrote (a very simple "calculate a+b" thing), but not for the mentioned slightly more complex code (3 instead of 2 inputs and 3 outputs instead of 1).
The super simple code which is working:
function pushbutton1_Callback(hObject, eventdata, handles) %the button to push
...some code...
global statText;
set(statText,'String',char(output));
function text1_CreateFcn(hObject, eventdata, handles) %the outputfield
global statText;
statText = hObject;