in reply to Re^2: Perl/Tk code structure
in thread Perl/Tk code structure
How complex would this job be?
Not complex at all.
Here is a silly script that when run with no options just gets lines from the keyboard and echos them back to the screen until the use enters '!bye':
#! perl -slw use strict; use threads; our $GUI //= 0; if( $GUI ) { require 'MyGui.pm'; async( \&MyGui::gui )->detach; } while( 1 ) { my $in = <STDIN>; exit if $in =~ '!bye'; print $in; } __END__ C:\test>MyGui-t hello hello goodbye goodbye !bye
But if you add the option to the command line C:\test>MyGui-t -GUI, it fetches lines from a Tk gui and echos the results to that gui instead.
The MyGui.pm module looks like this:
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( $_[1] ); } 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; 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( -a +fter => $ef ); $mw->repeat( 100, sub { $lb->insert( 'end', $Qout->dequeue ) while $Qout->pending; $lb->see( 'end' ); } ); $mw->bind( '<Return>', $enter ); $ef->focus( -force ); Tk::MainLoop(); } 1;
And that's it. Add three lines to the top of your existing program and put the module somewhere it will be found and you are done.
This is what the gui looks like doing the exact same entry sequence as shown for the non-gui session above just before hitting enter to quit the program.
|
---|