2014-10-11 2 views
2

У меня всегда была такая же проблема, и мне очень хотелось бы знать, есть ли у нее решение. Если я что-то вроде:Эффективно размыкать петлю при выходе фигуры Matlab

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 

Я всегда получаю какие-то ошибки, когда фигура вышла с кнопкой х:

Error using handle.handle/set 
Invalid or deleted object. 

Это не удивительно, потому что если я выхожу в то время как его чтения цикл, он все равно должен пройти через него, прежде чем он поймет, что он должен ломаться. Один из способов решения ошибок состоит в том, чтобы добавить «if ishandle (h)» везде, где я использую что-то, что используется вне цикла. Тем не менее, это не только спам моего кода с if/end почти в каждой строке, но и очень медленно выйти из кода. Это большая проблема, я не против большой ошибки или спама моего кода, но каждый раз, когда я ухожу, мне нужно ждать дополнительные 5 секунд, когда Matlab зависает по какой-то причине.

Это нормально? Есть ли более эффективный способ закрыть фигуру? Я думаю, что должен быть слушатель, когда нажата кнопка x на фигуре, которая просто остановит все ...

Это очень расстраивает и сводит меня с ума, любая помощь будет оценена по достоинству.

Спасибо,

Майк

+1

Я использую try set (h, ..) catch break end для этого, он отлично работает, но его можно считать уродливым. То, что также помогает, заключается в том, чтобы положить только инструкцию set после ishandle(), а остальное - до – MeMyselfAndI

ответ

3

Вы получаете ошибку систематически, потому что ваше время неправильно. Вы проверяете наличие дескриптора, затем вводите задержку 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 

Просто убедитесь, что ваша задержка не находится между проверкой дескриптора и обновлением объекта.


Это должно позаботиться о деле в вашем примере. Если ваш фактический код намного больше, подумайте об использовании CloseRequestFcn в figure properties. Это слушатель, о котором вы спрашивали.

Этот метод может считаться «более чистым», чем трюк выше, но он будет включать в себя передачу аргумента между базовым рабочим пространством и обратным вызовом фигуры, что не так уж и чисто, если вы спросите меня. Лучше всего сохранить этот метод для случаев, когда код принадлежит 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 

Для чего-либо более сложного, вы должны написать отдельную функцию, которая будет вызываться, когда эта цифра закрыта ,

+0

Спасибо, отличный ответ. –

+0

@MikeNelson. Рад, что смог помочь. Подумайте о «принятии» ответа, если он решит вашу проблему;) – Hoki