Issues exiting from a while loop when the figure is closed
조회 수: 22 (최근 30일)
이전 댓글 표시
I often need to make functions that can be terminated by a user who doesn't have access to the keyboard (and thus the all-powerful ctrl c). One method I turn to is checking whether the user has closed the figure window.
h = figure;
while ishandle(h),
data = rand(10000,10); %do some process
plot(data); %plot the results
drawnow %flush the graphics queue
end
This works very well provided the loop is simple . The problems begin to emerge when you are doing additional processing and making multiple plots on a figure.
h = figure;
while ishandle(h),
data = rand(10000,10); %process 1
plot(data); hold on %plot results of process 1
pause(0.001)%this is supposed to mimic a second process
plot(mean(data,2),':k'); hold off %plot the result of process 2
drawnow
end
If you try this, you'll notice that this loop will not exit every time you close the window. What often happens is that the code will miss the check on the figure handle because it's in the middle of doing something else, and the plot command forces Matlab to open a new figure window, at which point it has a new figure that it knows as 'h' and it will happily carry on plotting indefinitely.
So one method is to have this line (or something like it that sets some variable that is a check on whether the handle still exists) above each and every plotting command:
if ~ishandle(h);continue;end %check again if the window is open
This vastly complicates the readability of the code because in order to be completely reliable this must be replicated before each and every command that is related to plotting, including axis setting, scale changes, colormap commands, etc. I'd rather not resort to some variant of a 'close all' command, because there may be other windows open that need to stay open!
So, this has been very long winded, but here is my question: is there a way to force Matlab to make a unique figure handle that won't be automatically replaced? Or, alternatively, is there another method I haven't considered here?
댓글 수: 0
채택된 답변
Michael Haderlein
2014년 7월 28일
My suggestion is to not use the figure handle but the axes handle instead (they get a new number each time):
h=axes;
while ishandle(h),
data = rand(10000,10); %process 1
plot(data); hold on %plot results of process 1
pause(1)%this is supposed to mimic a second process
plot(mean(data,2),':k'); hold off %plot the result of process 2
drawnow
end
This way, if you close the window during the 1 second break, a new window will open, plotting process 2, but then the loop will end. If you even want to avoid this, I could only imagine to ask for the existence of h right before the plotting, e.g.
while...
data=...;
data2=...;
if ishandle(h)
plot(data)
plot(data2)
end
end
추가 답변 (1개)
Robert Cumming
2014년 7월 28일
force all of your plot, scale colourbars etc by specifying which axes/figure they are to be plotted on, i.e.
plot ( axesHandle, mean(data,2), ':k' );
xlim ( axesHandle, ....
etc....
This will throw an error if the axesHandle has been deleted when the plot command is issued.
You could put the whole while in a try catch - catching the error and checking what the error was (i.e. invalid handle) -> that means the user close the figure. Anything else was a different type of error.
댓글 수: 5
Michael Haderlein
2014년 7월 28일
Of course you can, but look what happens if the axes don't exist anymore (only with the plot function):
ha=axes; delete(ha), plot(ha,1:100)
Instead of an error, you'll get a plot with 100 points and all have the same x-values (=ha). It won't be seen as handle, it's just a number now. As said above, the xlim function will indeed throw an error, but I wouldn't use a function I actually don't need just to throw an error.
Robert Cumming
2014년 7월 28일
Ah - good spot.
However if the user was passing in x and y then it would throw an error...
참고 항목
카테고리
Help Center 및 File Exchange에서 Graphics Performance에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!