in reply to Perl:TK - standard output to text widget

I'm not sure what your project entails, but if you are using Tk, it would be good to be aware of fileevent. It gives you non-blocking reads.
#!/usr/bin/perl use warnings; use strict; use Tk; my $mw = new MainWindow; my $t = $mw->Text(-width => 80, -height => 25, -wrap => 'none'); $t->pack(-expand => 1); open(CHILD, "./read-stdout-piper 2>&1 |") or die "Can't open: $!"; $mw->fileevent(\*CHILD, 'readable', [\&fill_text_widget,$t]); MainLoop; sub fill_text_widget { my($widget) = @_; $_ = <CHILD>; if((defined $_) && ($_ > 5)){print chr(07)} $widget->insert('end', $_); $widget->yview('end'); }
And the sender script
!/usr/bin/perl $|++; for my $i ( 0 .. 10) { print $i, "\n"; sleep 1; } print "sleeping 5\n"; sleep 5; for my $i ( 0 .. 10) { print $i, "\n"; sleep 1; }

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re^2: Perl:TK - tail -f to text widget
by rehmanz (Novice) on Aug 16, 2010 at 23:41 UTC
    Now how can I modify this program to do a tail on a file. I have multiple tables in my main GUI window and need to tail the summary, detail and error file! I am stuck so any help would be greatly appreciated! Thanks in advance!
      You are better off getting rid of the tie to STDOUT, that is a hack of last resort. :-)

      Look at this. You could open multiple IPC connected filehandles, watch them with multiple fileevents, and insert the output into the same text widget, with different colored text.

      #!/usr/bin/perl use strict; use Tk; use IO::Handle; my $H=IO::Handle->new; open($H,"tail -f -n 50 z.txt |") or die $!; my $main = MainWindow->new; my $t = $main-> Scrolled('Text', -wrap=>'none')->pack(-expand=>1); $main->fileevent(\*$H,'readable',[\&fill,$t]); MainLoop; sub fill { my ($w) = @_; my $text; my $text =<$H>; $w->insert('end',$text); $w->yview('end'); }

      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku
        Thanks zentara! Worked to perfection....Here is my code that tails three separate files using the tabs....Cheers!
        use Tk; use Tk::NoteBook; use IO::Handle; my $S=IO::Handle->new; my $D=IO::Handle->new; my $E=IO::Handle->new; my $baseDir = "/"; my $sumFile = $baseDir."summary.log"; my $detFile = $baseDir."detail.log"; my $errFile = $baseDir."error.log"; open($S,"tail -f $sumFile |") or die $!; open($D,"tail -f $detFile |") or die $!; open($E,"tail -f $errFile |") or die $!; $mw = MainWindow->new(); $mw->geometry( "600x200" ); $book = $mw->NoteBook()->pack( -fill=>'both', -expand=>1 ); my $sumTab = $book->add( "Sheet 1", -bitmap => 'info'); my $detTab = $book->add( "Sheet 2", -bitmap => 'questhead'); my $errTab = $book->add( "Sheet 3", -bitmap => 'error'); my $sumText = $sumTab->Scrolled('Text', -wrap=>'none')->pack(-expand=> +1); my $detText = $detTab->Scrolled('Text', -wrap=>'none')->pack(-expand=> +1); my $errText = $errTab->Scrolled('Text', -wrap=>'none')->pack(-expand=> +1); $sumText->fileevent(\*$S,'readable',[\&fillSummary,$sumText]); $detText->fileevent(\*$D,'readable',[\&fillDetails,$detText]); $errText->fileevent(\*$E,'readable',[\&fillErrors,$errText]); MainLoop; sub fillSummary { my ($w) = @_; my $text = <$S>; $w->insert('end',$text); $w->yview('end'); } sub fillDetails { my ($w) = @_; my $text = <$D>; $w->insert('end',$text); $w->yview('end'); } sub fillErrors { my ($w) = @_; my $text = <$E>; $w->insert('end',$text); $w->yview('end'); }