我一直有同样的问题,我真的想知道是否有解决方案。如果我这样做:
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's垃圾邮件,退出代码的速度也非常慢。这是一个更大的问题,我不介意错误,或者发送垃圾邮件我的代码,但每次我退出时我都需要等待额外的5秒,因为某些原因Matlab会冻结。
这是正常的吗?有没有更有效的方法来关闭数字?我想在一个数字上点击x按钮时必须有一个监听器,这样就可以阻止一切......
这非常令人沮丧并让我发疯,任何帮助都会受到赞赏。
谢谢,
麦克
答案 0 :(得分:3)
你系统地得到了错误,因为你的时机错了。检查是否存在句柄,然后引入1ms延迟(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
对于任何更复杂的事情,你必须编写一个单独的函数,当关闭数字时将调用该函数。