1

我有这样的程序

...
$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() ,并且我想将“开始”按钮的标签更改为Cancel,这允许我单击该按钮以中断long_time_operation()循环。

我如何为它制作正确的代码?

4

2 回答 2

1

唯一真正的解决方案是使用多个线程并在后台线程中执行长操作。如果你想保持你的代码简单,你可以wxYield()用来处理这个事件处理程序内部的事件,但是请注意,由于重入,这可能(并且将会)导致难以调试的问题,所以至少你需要如果您这样做,请禁用 UI 的其余部分。

于 2014-07-09T08:39:43.250 回答
0

尝试使用 wxTimer 并在 on_click_start 函数中启动它。将长时间操作代码放在定时器的事件下(确保它不会重复触发,只需将定时器也停止在那里)。在您的长操作函数中使用一些全局变量来知道您是否要取消。如果您的按钮现在更改全局变量的值,以便您的长期代码知道这一点并从循环中取消/中断。

我不确定计时器事件下的循环是否会挂起您的 UI,但它似乎使用线程,因此这可能不会发生。无论如何尝试一下,当我需要类似的东西时,我总是使用 wxTimer(不要挂起 UI,也不要直接使用线程)。

于 2014-10-31T07:53:39.103 回答