package MyGuiStdin; our @ISA = qw[ Thread::Queue ]; sub TIEHANDLE { bless $_[1], $_[0]; } sub READLINE { $_[0]->dequeue(); } package MyGuiStdout; our @ISA = qw[ Thread::Queue ]; sub TIEHANDLE { bless $_[1], $_[0]; } sub PRINT { $_[0]->enqueue( join ' ', @_[ 1 .. $#_ ] ); } sub PRINTF { $_[0]->enqueue( sprintf $_[1], @_[ 2 .. $#_ ] ); } package MyGui; use strict; use warnings; use threads; use Thread::Queue; my $Qin = new Thread::Queue; my $Qout = new Thread::Queue; tie *STDIN, 'MyGuiStdin', $Qin; tie *STDOUT, 'MyGuiStdout', $Qout; sub gui { require Tk; require Tk::DialogBox; my $mw = Tk::MainWindow->new; my $lb = $mw->Listbox( -width => 80, -height => 24 )->pack; my $ef = $mw->Entry( -width => 70, -takefocus => 1 )->pack( -side => 'left' ); my $enter = sub { $Qin->enqueue( $ef->get ); $ef->delete(0, 'end' ); 1; }; my $do = $mw->Button( -text => 'go', -command => $enter)->pack( -after => $ef ); $mw->bind( '', $enter ); $ef->focus( -force ); my $doStdout = sub { if( $Qout->pending ) { my $output = $Qout->dequeue; $lb->insert( 'end', $output ) ; $lb->see( 'end' ); if( $output eq 'Enter three, 2-digit numbers: ' ) { my $db = $mw->DialogBox( -title => 'Three 2 digit numbers', -buttons => [ 'Ok' ] ); my $e1 = $db->add( 'Entry', -width => 3 )->pack( -side => 'left' ); my $e2 = $db->add( 'Entry', -width => 3 )->pack( -side => 'left', -after => $e1 ); my $e3 = $db->add( 'Entry', -width => 3 )->pack( -side => 'left', -after => $e2 ); $e1->focus( -force ); $db->Show; my $input = sprintf "%2d %2d %2d", $e1->get, $e2->get, $e3->get; $Qin->enqueue( $input ); } elsif( $output eq 'Enter a date and time: ' ) { my $db = $mw->DialogBox( -title => 'Date&time', -buttons => [ 'Ok' ] ); my $day = $db->add( 'Entry', -width => 2 )->pack( -side => 'left' ); my $mon = $db->add( 'Entry', -width => 2 )->pack( -side => 'left', -after => $day ); my $year= $db->add( 'Entry', -width => 4 )->pack( -side => 'left', -after => $mon ); my $hours = $db->add( 'Entry', -width => 3 )->pack( -side => 'left' ); my $mins = $db->add( 'Entry', -width => 3 )->pack( -side => 'left', -after => $hours ); my $secs = $db->add( 'Entry', -width => 3 )->pack( -side => 'left', -after => $mins ); $day->focus( -force ); $db->Show; my $input = sprintf "%2d/%02d/%02d %2d:%02d:%02d", $day->get, $mon->get, $year->get, $hours->get, $mins->get, $secs->get; $Qin->enqueue( $input ); } } }; $mw->repeat( 500, $doStdout ); Tk::MainLoop(); } 1;