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?

采纳的回答

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