in reply to Tk::Progressbar gives X Error

You can accomplish this in a much simpler way by setting some sort of cancel indication (a variable):

use Tk; use Tk::ProgressBar; use strict; use warnings; my $count; my $cancel; my $mw = new MainWindow(-title => "demo"); $mw->Button(-command => sub {do_something(\$count, \$cancel)}, -text = +> "Do Something")->pack(); $mw->Button(-command => sub {cancel(\$cancel)}, -text => "Cancel")->pa +ck(); my $pb = $mw->ProgressBar( -from => 0, -to => 100, -blocks => 100, -colors => [0, 'green', 50, 'yellow' , 80, 'red'], -variable => \$count )->pack(); MainLoop; sub do_something { my ($count_r, $cancel_r) = @_; $$count_r = 0; $$cancel_r = 0; while (!$$cancel_r & $$count_r < 100) { $$count_r ++; $mw->update(); sleep(1); } } sub cancel { my $cancel_r = shift; $$cancel_r = 1; }

One thing important here is to analyze your "unit of work". You only need to check cancel indication after the completion of each unit of work. This is safe and simple.

You can choose to check even during the unit of work, if your unit of work takes too long and you want a shorter response time. But you have to make sure the work can be fully cancelled, not leave something half broken there, and demage your data integrity.

Also if your unit of work is too big, you probably want to look at your analysis again.