Issues exiting from a while loop when the figure is closed

조회 수: 22 (최근 30일)
W. Owen Brimijoin
W. Owen Brimijoin 2014년 7월 28일
댓글: Robert Cumming 2014년 7월 28일
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?

채택된 답변

Michael Haderlein
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
W. Owen Brimijoin
W. Owen Brimijoin 2014년 7월 28일
Ahh yes, this is a possibility. Also your suggestion of grouping together all plotting in a single chunk of code would certainly do the trick (or you could go further and indeed break all the plotting out into its own nested function that's only called if 'h' is still a valid handle).
As with many things, it seems obvious once the solution is presented. Thanks for taking the time to help out.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Robert Cumming
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
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
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 CenterFile Exchange에서 Graphics Performance에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by