1

I have a program like this

...
$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 );
    }
}
...

My problem is when I click the Start button, on_click_start() will be called, and I want change the label of Start button to Cancel, that allow I to click the button to break out the long_time_operation() loop.

How do I make right code for it?

twjohn
  • 27
  • 1
  • 5

2 Answers2

1

The only real solution is to use multiple threads and perform the long operation in a background thread. If you want to keep your code simple, you can use wxYield() to handle the events from inside this event handler, but be aware that this may (and will) result in difficult to debug problems due to reentrancy, so at the very least you need to disable the rest of your UI if you're doing it like this.

VZ.
  • 21,740
  • 3
  • 39
  • 42
0

Try with a wxTimer and start it in your on_click_start function. Put the long time operation code under the event of the timer (ensure that it dont trigger repeteadly, just stop the timer there too). Inside your long operation function use some global var to know if you want to cancel. In the event of your button now change the value of your global var so your long term code knows about that and cancels/break from the loop.

I am not sure if a loop under the event of the timer can hang your UI, but it appears to use threads, so that may not happen. Try it anyway, i always use wxTimer when I need something like that (dont hanging the UI and not using threads directly).