我也经常遇到同样的问题,很想知道有没有解决办法。如果我做类似的事情:
figure
axis([-2 2 -2 2])
a=1;
h=rectangle('Position',[1,0,0.1,0.1]);
t=0;
while a==1
if ishandle(h)
t=t+0.1;
pause(0.001)
x=0.2*cos(t);
y=0.2*sin(t);
set(h, 'Position', [x, y,0.1,0.1])
else
break
end
end
当使用 x 按钮退出图形时,我总是会遇到某种错误:
Error using handle.handle/set
Invalid or deleted object.
这并不奇怪,因为如果我在读取循环时退出,它仍然必须经历它才能意识到它应该中断。解决错误的一种方法是在循环外部使用的任何地方添加“if ishandle(h)”。然而,这不仅会在几乎每一行都用 if/end 发送垃圾邮件,而且退出代码的速度也非常慢。这是一个更大的问题,我不太介意错误,或者垃圾邮件我的代码,但每次退出时我都需要额外等待 5 秒,Matlab 由于某种原因卡住。
这正常吗?有没有更有效的方法来关闭数字?我认为必须有一个监听器,当单击图形上的 x 按钮时,这只会停止一切......
这非常令人沮丧,让我发疯,任何帮助将不胜感激。
谢谢,
迈克
最佳答案
你会系统地得到错误,因为你的时机不对。您检查句柄是否存在,然后引入 1 毫秒延迟 (pause(0.001)
),最后更新对象。循环中的所有这些短代码执行得相当快,窗口的实际“关闭”有 99.99% 的机会在延迟期间发生。
如果您只是重新排序代码(将句柄检查放在延迟之后(最好是在更新对象之前),代码将正常运行,您只会收到错误在检查和对象更新之间发生实际“关闭”的时间为奇数 0.01%。
while a==1
t=t+0.1;
pause(0.001)
x=0.2*cos(t);
y=0.2*sin(t);
if ishandle(h)
set(h, 'Position', [x, y,0.1,0.1])
else
break
end
end
请注意,变量a
始终为1
,因此退出循环的唯一原因是删除对象h
。所以你可以简化你的循环,如:
while ishandle(h)
set(h, 'Position', [x, y,0.1,0.1])
t=t+0.1;
x=0.2*cos(t);
y=0.2*sin(t);
pause(0.001)
end
只需确保延迟不在句柄检查和对象更新之间。
这应该可以解决您示例中的情况。如果您的实际代码要大得多,请考虑使用 figure properties
中的 CloseRequestFcn
。这就是您要询问的监听器。
此方法可能被认为比上面的技巧“更干净”,但它将涉及在基础工作区和图形回调之间传递参数,如果你问我的话,这并不是那么干净。当您的代码属于 gui 并且不是从基础工作区中的脚本执行时,最好保留此方法。
虽然我不推荐将其用于如此简单的情况,但一个例子是:
hfig = figure('CloseRequestFcn', 'evalin(''base'', ''figExist=0'' )' ) ;
figExist = 1 ;
axis([-2 2 -2 2])
a=1;
h=rectangle('Position',[1,0,0.1,0.1]);
t=0;
while figExist
set(h, 'Position', [x, y,0.1,0.1])
t=t+0.1;
x=0.2*cos(t);
y=0.2*sin(t);
pause(0.001)
end
delete(hfig) %// now we have to manually delete the figure
对于更复杂的事情,您必须编写一个单独的函数,该函数将在图形关闭时调用。
关于matlab - 当图形退出Matlab时有效地中断循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26311107/