Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Tk gurus:

I want to have a text widget where I can display a running log from a process. Example code below. This all works fine except if the x-axis scroll bar is at it's maximum right hand position relative to the text widget and more text is printed to the widget the x-axis scrollbar moves to it's most left hand position. I want the scrollbar to stay at it's current postion.

This is my first attempt at using Tk.... I can't figure out how to control this - or if's it's controllable. Maybe there is a better method. All suggestions are most welome.

Thanks!

use strict; use Tk; my ($mainwindow, $menubar, $display, $text); my $counter = 0; $mainwindow = new MainWindow; $mainwindow->geometry("800x400"); $display = $mainwindow->Scrolled('Text', -relief=>'sunken', -borderwidth=>'2', -height=>'24', -scrollbars=>'se', '-width' => 40, '-wrap'=>'none'); $display->pack(-expand=>'1', -fill=>'both'); $text = $display->Subwidget('text'); # need this because yo +u can't tie to $display - main widget tie *STDOUT, ref $text, $text; create_gui_main(); $text->repeat( 1000, sub { goto \&mymain; }, ); MainLoop; sub mymain() { # This would normally be real text $counter++; print "this is a very long line we need a scrollbar on the x axis........ this is a very long line we need a scrollbar on the x axis........ this is a very long line we need a scrollbar on the x axis........ well the number is current = " . $counter . " \n"; } # ------------------------ # sub quitapp() { exit; } # ------------------------ # sub create_gui_main { my $menuitems = [ [Cascade => "~File", -menuitems => [ [Button => "~Quit", -command => \&quitapp], ] ], ]; if ($Tk::VERSION >= 800) { $menubar = $mainwindow->Menu(-menuitems => $menuitems); $mainwindow->configure(-menu => $menubar); } else { $mainwindow->Menubutton(-text => "Pseudo menubar", -menuitems => $menuitems)->pack; } } __END__

Replies are listed 'Best First'.
Re: Tk and scrollbars
by eserte (Deacon) on Jul 09, 2004 at 09:22 UTC
    You can remember the scrollbar position before printing to the widget and restore the position after printing. E.g:
    sub mymain() { # This would normally be real text my(@old_x_view) = $text->xview; $counter++; print "this is a very long line we need a scrollbar on the x axis... +..... this is a very long line we need a scrollbar on the x axis..... +... this is a very long line we need a scrollbar on the x axis....... +. well the number is current = " . $counter . " \n"; $text->xview(moveto => $old_x_view[0]); }
      Thank you - my(@old_x_view) = $text->xview; $text->xview(moveto => $old_x_view[0]); this works perfectly --jammin
Re: Tk and scrollbars
by SciDude (Friar) on Jul 09, 2004 at 03:56 UTC

    Did you want the single quotes around '-wrap' and '-width' ?

    Also, your "very long line" had line breaks in my downloaded version. Here are my modest hacks to activate the horizontal scroll bar:

    #!/usr/bin/perl use strict; use Tk; my ($mainwindow, $menubar, $display, $text); my $counter = 0; $mainwindow = new MainWindow; $mainwindow->geometry("800x400"); $display = $mainwindow->Scrolled('Text', -relief=>'sunken', -borderwidth=>'2', -height=>'24', -scrollbars=>'se', '-width' => 40, -wrap=>'none'); $display->pack(-expand=>'1', -fill=>'both'); $text = $display->Subwidget('text', -scrollbars=>'se', -wrap=>'none') +; # need this because you can't tie to $display - main widg +et tie *STDOUT, ref $text, $text; create_gui_main(); $text->repeat( 1000, sub { goto \&mymain; }, ); MainLoop; sub mymain() { # This would normally be real text $counter++; print "this is a very long line we need a scrollbar on the x axis... +..... this is a very long line we need a scrollbar on the x axis..... +... this is a very long line we need a scrollbar on the x axis....... +. well the number is current = " . $counter . " \n"; } # ------------------------ # sub quitapp() { exit; } # ------------------------ # sub create_gui_main { my $menuitems = [ [Cascade => "~File", -menuitems => [ [Button => "~Quit", -command => \&quitapp], ] ], ]; if ($Tk::VERSION >= 800) { $menubar = $mainwindow->Menu(-menuitems => $menuitems); $mainwindow->configure(-menu => $menubar); } else { $mainwindow->Menubutton(-text => "Pseudo menubar", -menuitems => $menuitems)->pack; } } __END__

    SciDude
    The first dog barks... all other dogs bark at the first dog.