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.
Related
This question already has answers here:
Stop A GUI in a middle of process in MATLAB
(2 answers)
How can I loop indefinitely, but stop on some condition(s)?
(2 answers)
Closed 4 years ago.
I am writing a matlab script that will perform calculations in a for loop, but would like it to break out of the for loop when 'return' is entered. I found a function that will listen for keystrokes and modified it to know when 'return' is pressed, but I can't figure out how to make it control what is going on in the main script.
Pseudo Code:
h_fig = figure;
set(h_fig,'KeyPressFcn',#myfun)
for ii = 1:50
break when enter is pressed
end
function y = myfun(src,event)
y = strcmp(event.Key,'return');
%disp(event.Key);
if y == 1
fprintf('Enter key pressed')
return
end
end
It seems like you are creating the window only so you can capture the return key press. If this is the case, there is a better alternative: kbhit (in Octave a similar function with the same name comes built-in). Simply copy the kbhit.m file from that File Exchange submission to your current folder (or any directory that you can add to your MATLAB path using addpath), and do as follows:
kbhit('init');
for ii = 1:50
if kbhit == 13
break
end
% computations here...
end
If you want to use a window anyway, the right way to do so is to poll the "CurrentCharacter" property of the figure window:
h_fig = figure;
set(h_fig,'CurrentCharacter','') % use this if the figure has been around for longer, to reset the last key pressed
for ii = 1:50
drawnow % sometimes events are not handled unless you add this
if double(get(h_fig,'CurrentCharacter'))==13
break
end
% computations here...
end
I could not get the above code to work in Octave, it seems that it doesn't update figure properties even with drawnow, not sure why. But I'm fairly sure the above works with MATLAB.
I have a while loop inside of which I have to use a plot and a chasePlot function.
The problem is, it comes up with a new window figure each time the loop runs. I somehow want a single frame which can be updated rather than each time making a new window and figure for it.
Anybody knows how to prevent a new figure in each loop so that one figure is there and that keeps on updating.
Don't use 'figure' before the 'plot' command and the code will keep overwriting every time on the same figure. You can also use the 'drawnow limitrate' command for better visualization. See an example below:
clc; close all; clear all;
x = 0 :100 :1e5;
y = zeros(size(x));
for n = 1:numel(x)
y(n) = sin(x(n));
plot(x(1:n), y(1:n));
drawnow limitrate;
end
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
I am trying to run a program that opens a webcam, takes a screenshot, processes it, and shows the output. My code runs correctly and I am getting output, but when I close the output window I get this error every-time:
Matlab System Error: Matlab has encountered an internal problem and needs to close.
As I am new to Matlab can anyone help me? I am using Windows 8 operating system and Matlab R2013a.
This is the code:
clear all;
close all;
clc;
video=videoinput('winvideo',1);
preview(video);
while(true)
data=getsnapshot(video);
R=data(:,:,1);
G=data(:,:,2);
B=data(:,:,3);
for i=1:768
for j=1:1024
if(R(i,j)<128)
out(i,j)=1;
else
out(i,j)=0;
end
end
end
cla; % Prevent stuffing too many images into the axes.
imshow(out);
drawnow;
end
Here's some simpler code that replicates the error on Windows or on Mac for me (R2013b, built-in FaceTime HD camera):
clear all;
close all;
% video = videoinput('macvideo',1);
video = videoinput('winvideo',1);
while true
data = getsnapshot(video);
cla;
imshow(data);
drawnow;
end
Run the above and close the the window after it draws the image and you may be able to get it to crash. The strange thing is that after I reliably made it crash a few times it stopped doing it.
What is going on?
The fact that the error went away randomly for me makes me suspect some sort of race condition. You code isn't particularly correct, but Matlab shouldn't be crashing hard like this, so it should be reported as a bug.
How can you fix this?
The problem is that you're closing a window that is being drawn to inside of an infinite while loop. You need to break the while loop when the figure is closed. And you might also want to perform some cleanup such as deleting the video object. Here's some nice fast code that shouldn't produce an error :
clear all;
close all;
clc;
if ispc
video = videoinput('winvideo',1);
elseif ismac
video = videoinput('macvideo',1);
else
video = videoinput(imaq.VideoDevice);
end
% preview(video);
% Create figure and get handle to image data
data = getsnapshot(video);
R = data(:,:,1);
out = double(R < 128);
h = imshow(out);
while true
data = getsnapshot(video);
R = data(:,:,1);
out = double(R < 128);
if ishghandle(h) % Only if figure still open
set(h,'CData',out); % Replace image data
else
break;
end
end
delete(video); % Clean up
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,