Problem with "cancel" button (waitbar). User input is ignored.
13 views (last 30 days)
Show older comments
Hi folks
I'm a bit puzzled about an issue I (most likely) introduced into my code. The programme in question opens a relatively primitive GUI with a number of options to handle experimental data from our sensors. One of the buttons involves a spectral analysis (power spectral density and the like) of the data files located in the same directory as the MATLAB file (or a stand-alone executable). The data sets can be relatively large and thus the analysis can take some time. Misclicks happen, so I added a "Cancel" button to the progress bar (simple waitbar function, copied & pasted from MATHWORKS examples). This in turn opens another function deleting every figure and every output file the programme has created up to this point. As of late, the programme ignores me clicking the cancel button. Getappdata shows that the associated variable doesn't change and that the operator input is completely ignored.
I know the code is not winning any beauty contests, but it worked fine up until recently. There has been a major update involving some streamlining/restructuring in the core programme. I guess that I've screwed up somewhere and I was wondering if you guys could perhaps point me in the right direction?
Matlab version is R2011, however, the problem also occurs with the trial version of R2023. Used toolboxes are "signal processing" and "curve fitting".
Main structure looks like this:
function varargout = SW0110_Beta(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @SW0110_Beta_OpeningFcn, ...
'gui_OutputFcn', @SW0110_Beta_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
%...
function SW0110_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles)
%...
function varargout = SW0110_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
%...
function pushbutton_Callback(hObject,~,handles)
%...
%Plus a few more functions like this
%...
A simple GUI with a couple of buttons and input lines put together in Guide. Nothing fancy. If the operator hits the "Compile" button in the main window we get to
function pushbutton_Callback(hObject,~,handles)
%...
%lots of data reading, handling and output generation
fwait_analyze = waitbar(0,'1','Name','Analysing Data - Please Wait','CreateCancelBtn','setappdata(gcbf,''canceling'',1)');
setappdata(fwait_analyze,'canceling',0);
waitbar(0,fwait_analyze,sprintf('0 %%'));
%...
%simple loop i=1:dat_numb
if getappdata(fwait_analyze,'canceling') == 1
%second loop v=1:i & second progress bar
fcancel = waitbar(0,'1','Name','Deleting OutPut Files - Please Wait');
waitbar(0,fcancel,sprintf('0 %%'));
%remove results/output files
waitbar(v/dat_numb,fcancel,sprintf('%2.0f %%',v/i*100-1))
%end v loop
%delete fwait_analyze & fcancel
return
end
waitbar(i/dat_numb,fwait_analyze,sprintf('%2.0f %%',i/dat_numb*100-1))
%end i loop
%...rest of the function
end
As simple as it gets with a second progress bar indicating the removal process. Any operator input (clicking the cancel button) is ignored and getappdata is always returning '0' in this framework. Running the code on its own works fine and the user input is properly recognized.
Not overly surprising, version 2 with uicontrol exhibits the same problem.
function pushbutton1_Callback(hObject,~,handles)
%...
fwait_analyze = waitbar(0,'1','Name','Analysing Data - Please Wait');
uicontrol('Parent',fwait_analyze,'Style','pushbutton','String','Cancel','Units','normalized','Position',[0.75 0.1 0.2 0.3],'Visible','on','CallBack',@CancelB);
waitbar(0,fwait_analyze,sprintf('0 %%'));
%...
%loop i=1:dat_numb
waitbar(i/dat_numb,fwait_analyze,sprintf('%2.0f %%',i/dat_numb*100-1))
%end i loop
%rest of the function
end
%...
function CancelB(~,~)
fcancel = waitbar(0,'1','Name','Deleting OutPut Files - Please Wait');
waitbar(0,fcancel,sprintf('0 %%'));
%loop v=1:dat_numb
%remove results/output files
waitbar(v/dat_numb,fcancel,sprintf('%2.0f %%',v/dat_numb*100-1))
%end v loop
%delete fwait_analyze & fcancel
return
end
The code here is just for indication to give you can idea what I'm trying to accomplish. I'm more interested in understanding why MATLAB is doing what it is doing. Any comment would be greatly appreciated.
Thanks a lot + kind regards
Christian
7 Comments
Rik
on 1 Sep 2023
I haven't read all comments and code in detail, but this reminds me of situations where you should use drawnow to flush the queue of callbacks. Without it, clicking the cancel button might not do anything until much later.
If this is indeed the case, going through the code line by line will not actually help you find the problem, since after executing a line and pausing, the callback queue is flushed.
Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!