I don't have
Tkx going, but in Tk, you could do it like this. In the thread, when you launch your program, don't use system, but use a form of IPC which will return a pid for the batch file running. Then stuff the pid in a threads shared variable,
then in your main Tkx script, the cancel button would invoke "killfam 9, $pid". Use
Proc::Killfam to make sure you kill not only the batch file, but any shell which gets invoked to run it.
A simple example in Tk, to show the principle. Tkx should work similarly.
#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;
use Tk;
my %shash;
#share(%shash); #will work only for first level keys
my %hash;
share ($shash{'go'});
share ($shash{'fileno'});
share ($shash{'pid'});
share ($shash{'die'});
$shash{'go'} = 0;
$shash{'fileno'} = -1;
$shash{'pid'} = -1;
$shash{'die'} = 0;
$hash{'thread'} = threads->new(\&work);
my $mw = MainWindow->new(-background => 'gray50');
my $text = $mw->Scrolled('Text')->pack();
my $startb = $mw->Button( -text => 'Start',
-command=>sub{
$shash{'go'} = 1;
$mw->after(100); #give pipe chance to startup
my $fileno = $shash{'fileno'};
print "fileno_m $fileno\n";
open (my $fh, "<&=$fileno") or warn "$!\n";
# filevent works but may not work on win32,
# but you can use a timer instead as shown below
$mw->fileevent(\*$fh, 'readable', );
while(<$fh>){
$text->insert('end',$_);
$text->see('end');
$mw->update;
}
# on Win32 (untested by me) you will need
# a timer instead of fileevent
# my $repeater;
# $repeater = $mw->repeat(10,
# sub {
# my $bytes = sysread( "<&=$fileno", my $buf, 8192);
# $text->insert('end',$buf);
# $text->see('end');
# if( $shash{'go'} == 0 ){ $repeater->cancel }
# }
# );
}
)->pack();
my $stopb = $mw->Button( -text => 'Stop/Exit',
-command=>sub{
$shash{'die'} = 1;
kill 9,$shash{'pid'};
$hash{'thread'}->join;
exit;
},
)->pack();
MainLoop;
##################################################################
sub work{
$|++;
while(1){
if($shash{'die'} == 1){ return };
if ( $shash{'go'} == 1 ){
#run your command here, and try to find a way to capture it's
+output
# on win32 you may need to use IPC::Run in the thread
#use a win32 command that gives continous output
# on linux I use top
my $pid = open(FH, "top -b |" ) or warn "$!\n";
my $fileno = fileno(FH);
print "fileno_t->$fileno\n";
$shash{'fileno'} = $fileno;
$shash{'pid'} = $pid;
$shash{'go'} = 0; #turn off self before returning
}else
{ select(undef,undef,undef,.1) } #short sleep
}
}
#####################################################################