Abort current script on closing waitbar - matlab

I am using a waitbar like this:
h = waitbar(0,'Please wait...');
for i=1:100, % computation here %
waitbar(i/100)
% other operation here
end
close(h)
I would like to stop this script if the user close the waitbar (clicks the X of the window), without having to add a Cancel button.
Is there any way to do it?

You can test whether h is a valid handle, and exit the loop otherwise. Insert the following into your loop:
if ~ishandle(h)
break
end

You can try something like this :
if ishandle(h),
close(h);
% Your code here
else
%waitbar has been closed by the user
% call throw, return, or break
end
Hope it helps,

Related

WindowKeyPressFcn executes after program interruption

I want to detect pressing of the key, when running matlab script in while loop. At the moment, I only want to display success, after pressing of the key. Unfortunately, the message is displayed only after program interruption (CTRL+C) not during program run. Here is the code:
% Init of callback
fig = gcf;
set(fig,'WindowKeyPressFcn',#keyPressCallback);
% keyPressCallback function
function keyPressCallback(source,eventdata)
keyPressed = eventdata.Key;
if strcmpi(keyPressed,'space')
disp('success');
end
end
You need to break the cycle of the script which is running so that Matlab will process other events, in essense your keypress. You can do that by adding a drawnow inside you while loop, the code below should give you enough to incorporate in your own:
fig = figure;
set(fig,'WindowKeyPressFcn',#(hFig,hEvent)fprintf('pressed key %s\n',hFig.CurrentKey) );
drawnow();
while true
if ~ishandle(fig); break; end
drawnow();
end

How to stop figure repeatedly popping up after closing animation

Lately I've started to make a crank mechanism animation. The animation works well, but when I tried to close the Figure 1 window it just keeps popping up.
I don't know how to stop this?
Code:
clc;
clear all;
radius=2;
vzdOdKliky=6;
bod1=[0,0];
axis(gca, 'equal');
mezera=[-4,8,-4,8];
axis(mezera);
speed=1;
for time=1:200
theta=speed*(time/10);
bod2=radius*[cos(theta),sin(theta)];
alfa=asin(radius*sin(theta)/vzdOdKliky);
bod3=[(radius*cos(theta)+vzdOdKliky*cos(alfa)) 0];
klika=line([bod1(1),bod2(1)],[bod1(2),bod2(2)]);
klouzM=line([bod2(1),bod3(1)],[bod2(2),bod3(2)]);
trajB2=viscircles([0,0],radius,'LineStyle',':');
kruhB1=viscircles(bod1,0.3);
kruhB2=viscircles(bod2,0.3);
kruhB3=viscircles(bod3,0.2);
pause(0.001);
delete(klika);
delete(kruhB1);
delete(kruhB2);
delete(kruhB3);
delete(klouzM);
end
Your loop continues regardless of whether you've closed the figure or not.
Include a check on the figure's existence each loop like so:
% Open figure and store to variable for checking later
fg = figure;
% ... your setup code ...
for time = 1:200
% Check if the figure still exists
if ~isvalid(fg)
% Exit looping, figure has been closed
break
end
% ... other code in the loop ...
end
If you wanted to be less elegant, you could always hit Ctrl+C to terminate your script.

How to Loop Subplots with Updated Outputs in Matlab?

I want to create a frontend where the user can browse pictures forward by pressing Enter.
Pseudo-Code
hFig=figure
nFrames=5;
k=1;
while k < nFrames
u=signal(1*k,100*k,'data.wav'); % 100 length
subplot(2,2,1);
plot(u);
subplot(2,2,2);
plot(sin(u));
subplot(2,2,3);
plot(cos(u));
subplot(2,2,4);
plot(tan(u));
% not necessary but for heading of overal figure
fprintf('Press Enter for next slice\n');
str=sprintf('Slice %d', k);
mtit(hFig, str);
k=k+1;
keyboard
end
function u=signal(a,b,file)
[fs,smplrt]=audioread(file);
u=fs(a:b,1);
end
where
something is wrong in updating the data because pressing CMD+Enter increases k by one but does not update the data. Sometimes (rarely), the data is once the next iteration.
something is wrong with while's condition because k can be bigger than nFrames. keyboard just keep asking for more inputs.
My mistake earlier in Error-Checking
I had earlier a problem where the closure of the window lead to the crash of the application. I include this here because I mentioned a problem about it in the comment of one answer. I avoid the problem now by
hFig=figure;
n=5;
k=1;
while k<nFrames
% for the case, the user closes the window but starts new iteration
if(not(ishandle(hFig)))
hFig=figure;
end
...
end
which creates a new Figure if the earlier was closed by the user.
I tried unsuccessfully putting hFig=figure; inside the while loop's if clause earlier to avoid repetition in the code.
Please, let me know if you know why you cannot have the handle hFig in the while loop's if clause.
How can you loop subplots with updated outputs in Matlab?
To stop the script waiting for an input from the user you should use input instead of keyboard.
Actually keyboard makes your script entering in a debug mode. It stops the executino of the script as (like a breakpoint) allowing the user to, for example, check the value of a variable.
You can modify your scripr as follows (modification are at the end of your script, identified by "UPDATED SECTION):
hFig=figure
nFrames=5;
k=1;
while k < nFrames
u=signal(1*k,100*k,'handel.wav'); % 100 length
subplot(2,2,1);
plot(u);
subplot(2,2,2);
plot(sin(u));
subplot(2,2,3);
plot(cos(u));
subplot(2,2,4);
plot(tan(u));
% not necessary but for heading of overal figure
%
% UPDATED SECTION
%
% Use the string "Press Enter for next slice\n" as the prompt for the
% call to "input"
%
% fprintf('Press Enter for next slice\n');
% str=sprintf('Slice %f', k);
% Use %d instead of "%f" to print integer data
str=sprintf('Slice %d', k);
mtit(hFig, str);
k=k+1;
% Use "input" instead of "keyboard"
% keyboard
input('Press Enter for next slice\n')
end
Hope this helps.
Qapla'

Exit matlab script once all figure windows are closed

I want to stop the execution of script once all window figures are closed (i.e when I manually finish closing each figure window with a click). I tried doing:
x = 1:10;
plot(x,x);
while ~isempty(findall(0,'Type','Figure'))
if isempty(findall(0,'Type','Figure'))
exit
else
continue
end
end
However with the above code i) no figure is displayed and ii) the loop never ends. So my question is: how can exit matlab execution once all figure windows are closed?
Instead of polling in a loop, you can use waitfor
f(1)=figure();
f(2)=figure();
x = 1:10;
plot(x,x);
drawnow;
for ix=1:numel(f)
waitfor(f(ix));
end
All you need is to update callbacks. For this purpose, use drawnow function inside your while loop. If you don't want to exit matlab, do not use exit. Your programm script will stop automatically after it will finish while loop:
x = 1:10;
plot(x,x);
while ~isempty(findall(0,'Type','Figure'))
drawnow
end

Matlab waitbar - close all doesn't work

I have some code which creates a waitbar:
if long_process %user specifies this true/false
h = waitbar(1/4, msg);
end
process(arg1,arg2);
Process is some function which does some plotting. If I do CTRL-C somewhere in process and I get left with a figure window I can just do close all and the figure disappears. However, the waitbar stays. I don't know how to make that thing close with 'close all'.
The reason this is bothering is because when I start debugging I often end up having 20+ waitbars open. 'close all' then comes in handy.
Actually, the close function gives you some more "forceful" options:
close all hidden
close all force
And if for some reason those don't work, one "nuclear" option you have is to delete all figures, including those with hidden handles, as suggested in the close and waitbar documentation:
set(0, 'ShowHiddenHandles', 'on');
delete(get(0, 'Children'));
You may find it easiest to create your own helper function to do this for you (and return the state of 'ShowHiddenHandles' to its default 'off' state) so you don't have as much to type:
function killEmAll
set(0, 'ShowHiddenHandles', 'on');
delete(get(0, 'Children'));
set(0, 'ShowHiddenHandles', 'off');
end
...And even a third option is to try and avoid the problem altogether (if the organization of your code allows it) by using onCleanup objects! If you run the following sample code, the waitbar should be automatically deleted for you when you CTRL-C out of the infinite loop:
function runprocess
h = waitbar(1/4, 'la la la...');
waitObject = onCleanup(#() delete(h));
process();
end
function process
i = 1;
while (i > 0)
i = i + 1;
end
end