Как отменить долгую операцию в WxPerl
У меня есть такая программа
...
$self->{bn1}=Wx::Button->new( $tb1, -1, 'Start');
EVT_BUTTON( $self, $self->{bn1}, \&on_click_start );
...
...
sub on_click_start
{
my( $this, $event ) = @_;
$this->{bn1}->SetLabel("Cancel");
$event->Skip;
for (...) {
long_time_operation();
last if ( Cancel_clicked );
}
}
...
Моя проблема в том, что когда я нажимаю кнопку " Пуск", вызывается on_click_start(), и я хочу изменить метку кнопки " Пуск" на " Отмена", что позволяет мне нажимать кнопку, чтобы разорвать цикл long_time_operation().
Как мне сделать правильный код для него?
2 ответа
Единственное реальное решение - использовать несколько потоков и выполнять длительные операции в фоновом потоке. Если вы хотите сохранить свой код простым, вы можете использовать wxYield()
для обработки событий из этого обработчика событий, но имейте в виду, что это может (и будет) приводить к трудностям при отладке из-за повторного входа, поэтому, по крайней мере, вам нужно отключить остальную часть вашего пользовательского интерфейса, если вы делаете это как это.
Попробуйте использовать wxTimer и запустите его в функции on_click_start. Поместите код длительной операции под таймером (убедитесь, что он не срабатывает постоянно, просто остановите таймер там же). Внутри вашей долгой операции используйте какой-нибудь глобальный var, чтобы знать, хотите ли вы отменить. В случае вашей кнопки теперь измените значение вашей глобальной переменной, чтобы ваш долгосрочный код знал об этом и отменял / прерывал цикл.
Я не уверен, может ли цикл под событием таймера повесить ваш пользовательский интерфейс, но он, кажется, использует потоки, так что это может не произойти. Попробуйте в любом случае, я всегда использую wxTimer, когда мне нужно что-то подобное (не вешайте интерфейс и не используйте потоки напрямую).