How to use 'CancelRequested' property for a progress bar?

22 views (last 30 days)
I currently have an App Designer program set up to run calculations in batches. While running the batch calculations, I'd like to have a way to stop the process without getting a bunch of errors (which is what happens when I close the app or progress bar window). Using the 'Cancel' button in the dialog box as a way to kick the program out of the loop appears to be the right choice, but the documentation for this feature is too sparse to be of any use. Has anyone gotten this feature to work and willing to share how to code it?
Thanks in advance.

Accepted Answer

Cameron B
Cameron B on 13 Jan 2020
fig = uifigure;
dlg = uiprogressdlg(fig,'Title','Wait',...
'Message','Starting','Cancelable','on','CancelText','Stop this');
wholeRandNum = 37;
for ii = 1:wholeRandNum
%you can put all your other code here
if isempty(findobj(fig)) == 1
dlg.CancelRequested = 1;
end
if dlg.CancelRequested == 1
disp('You Hit Cancel or Exited')
delete(fig)
return
end
dlg.Value = ii/wholeRandNum;
dlg.Message = sprintf('%12.2f%% complete',ii/wholeRandNum*100);
pause(0.1)
end
  15 Comments
Joseph
Joseph on 27 Apr 2023
Hi guys, I'm having the same issue as Jessica was, I can't seem to trigger the cancel button on my porgress bar. All I want it to do is to terminate the serial connection to my hardware LDS1000 which should eventually lead the code to fail on the next iteration of the loop as it won't be able to write any data to it if the connection had been terminated, but whatever it is that I try I can't seem to get the cancel button to work. I have read all the comments on this thread and I still can't get it to work, any help with this issue would be massively appreciated! I'm sure there's a simple fix that I'm missing
function Plot(app)
for index = 1:1:app.n
pause(1.5)
writeline(app.LDS1000,'1TP'); % Measure the current value in the Y axis
data_y = readline(app.LDS1000); % Read the current value in the Y axis (with the command aatached to it) e.g. TP-1.2 or TP0.4
k_1 = [] ;
k_1 = strfind(data_y,'-','ForceCellOutput',true); % When the data is read and it isn't a 0.y value there is a dash between the command 'TP' and the numerical value,
if k_1{1} == 4 % hence the characters are separated at the dash, so the dash will be the 4th value hence k_1 == 4
d_1 = regexp(data_y,'\-','split'); % extract the numerical value
y = str2double(d_1); % convert in to a double
pause (0.5)
% However, when the data is extracted and it is a 0.y value this doesn't include a dash between the command 'TP' and the numercial value, hence the characters are separated at P
else k_1{1} == 0; %hence the characters are separated at P instead and this only occurs when k does not equal 4 as teh dash doesn't exist hence it is not the value
d_1 = regexp(data_y,'\P','split'); % extract the numerical value
y = str2double(d_1); % convert in to a double
pause (0.5)
end
writeline(app.LDS1000,'2TP'); % Repeat the whole precoess above however now for Y
data_z = readline(app.LDS1000);
k_2 = [] ;
k_2 = strfind(data_z,'-','ForceCellOutput',true);
if k_2{1} == 4;
d_2 = regexp(data_z,'\-','split');
z = str2double(d_2);
pause (0.5)
else k_2{1} == 0;
d_2 = regexp(data_z,'\P','split');
z = str2double(d_2);
pause (0.5)
end
% Reading curent vlues from Heidenhain
write(app.ND280,app.ESC,"char");
write(app.ND280,app.A0100_p,"char");
write(app.ND280,app.CR,"char");
Heid_x = read(app.ND280,16,"uint8");
Heid_X_2 = char(Heid_x);
Heid_Out = string(Heid_X_2);
H_1 = [];
H_1 = regexp(Heid_Out,'\s','split');
if H_1{1,5} ~= ""
H_2 = H_1{1,5};
H_3 = eraseBetween(H_2,6,6);
H_4 = str2double(H_3);
else H_1{1,4} ~= ""
H_2 = H_1{1,4};
H_3 = eraseBetween(H_2,7,7);
H_4 = str2double(H_3);
end
app.X_Heid(1,index) = H_4;
% Plotting and interpolating the read values
if index == 1 % To interpolate it requires to values in X and Y/Z
app.Z(1) = z(1,2); % hence, the initial values for Y/Z are just
app.Y(1) = y(1,2); % plotted which are Z(1) and Y(1)
xlim(app.UIAxes,[-app.s app.s]); % X limit is 50 to -50 on the figure
ylim(app.UIAxes,[-app.s app.s]); % Y limit id 50 to -50 on the figure
title(app.UIAxes,'Reflection Angle in Y and Z vs Stroke');
xlabel(app.UIAxes,'Slide Translation mm');
ylabel(app.UIAxes,'Reflection Angle \mu\theta');
h = animatedline(app.UIAxes,app.X(1,index),app.Y(1,index),'Color','red','LineStyle','-','Marker','*','MarkerSize',2);
g = animatedline(app.UIAxes,app.X(1,index),app.Z(1,index),'Color','green','LineStyle','-','Marker','o','MarkerSize',2);
addpoints(h,app.X(1,1),app.Y(1,1)); % Y(1) values plotted
addpoints(g,app.X(1,1),app.Z(1,1)); % Z(1) values plotted
drawnow;
else index >= 2; % Once an initial value has been obatined all future
app.Z(index) = z(1,2); % nodes will have a previous node, hence the Y/Z
app.Y(index) = y(1,2); % for the current node are read
xx1 = linspace(app.X(1,index),app.X(1,(index-1)),2); % Creating the sample points between the current node and the previous one
yy1 = interp1(app.X(1,(index-1):index),app.Y(1,(index-1):index),xx1); % Interpolating between the current node and the previous one in Y
zz1 = interp1(app.X(1,(index-1):index),app.Z(1,(index-1):index),xx1); % Interpolating between the current node and the previous one in Z
for ci= 2:-1:1
addpoints(h,xx1(ci),yy1(ci)); % Adding the interpolated points for Y
addpoints(g,xx1(ci),zz1(ci)); % Adding the interpolated points for Z
pause(0.1);
end
end
h = animatedline(app.UIAxes,app.X(1,index),app.Y(1,index),'Color','red','LineStyle','-','Marker','*','MarkerSize',2);
g = animatedline(app.UIAxes,app.X(1,index),app.Z(1,index),'Color','green','LineStyle','-','Marker','o','MarkerSize',2);
hold off
legend(app.UIAxes,{'Y','Z'});
drawnow
% Displaying current vlaues:
%y
y_current = num2str(app.Y(index));
app.YEditField.Value = y_current;
%z
z_current = num2str(app.Z(index));
app.ZEditField.Value = z_current;
%x_ACS
x_current = num2str(app.X(index));
app.XACSmmEditField.Value = x_current;
%x_Heid
x_Heid_current = num2str(app.X_Heid(index));
app.XHeidmmEditField.Value = x_Heid_current;
pause(1)
di = uiprogressdlg(app.progress,'Title','Progress Bar','Message','Progress','Cancelable',1);
di.Value = index/app.n;
Value = round(di.Value*100);
Vally = num2str(Value);
percent = '%';
if di.CancelRequested == 1
close(di)
app.LDS1000 = [];
elseif di.CancelRequested == 0
break
end
end
end
Levi Blake
Levi Blake on 27 Apr 2023
Joseph, why do you have break when di.CancelRequested == 0? I believe that would cause your code to kick out of the loop even when you haven't pressed the cancel button, which doesn't sound like what you want.
Have you tried moving break to take place under di.CancelRequested==1 after you close the figure and blank out app.LDS1000? Generally you shouldn't need a case for elseif di.CancelRequested==0.

Sign in to comment.

More Answers (1)

Cameron B
Cameron B on 13 Jan 2020
Edited: Cameron B on 13 Jan 2020
progressbar = waitbar(0,'Determining optimum slope','CreateCancelBtn','setappdata(gcbf,''Cancel'',1)');
wholeRandNum = 215;
for ii = 1:wholeRandNum
%you can put all your other code here
if getappdata(progressbar,'Cancel') == 1
delete(progressbar)
disp('You Hit Cancel or Exited')
return
end
pause(0.1)
waitbar(ii/wholeRandNum,progressbar,sprintf('%12.2f%% complete',ii/wholeRandNum*100));
end
delete(progressbar)

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!