Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Scrolling data in Tk

by davies (Parson)
on Nov 20, 2007 at 11:58 UTC ( #651906=perlquestion: print w/replies, xml ) Need Help??
davies has asked for the wisdom of the Perl Monks concerning the following question:

The problem:

I want to report phishing spam. To do this, I want to do various analyses of the spam, so that I can (for example) tell the bank which headers are my ISP's internal stuff and where the real injection point is. My plan is to get various outputs from things like whois, mark the rows I want in my final LART, and then output them to a single screen so that I can do a single cut & paste rather than the dozen or so I need at present.

The issue:

I can get whois output into Perl and output it with checkboxes. However, it's more than a screen long, and I can find no sensible way of scrolling.

The code:
use strict; use warnings; use diagnostics; use Tk; use Tk::Pane; use IO::Socket; my $nVOffset = 20; my $nHOffset = 18; my $wMain = MainWindow->new; $wMain->geometry('1020x700'); $wMain->toplevel->resizable(0,0); my $frame = $wMain->Scrolled('Frame', -scrollbars => 'e', -height => 680, -width => 1000) ->place(-x => 0, -y => 20); #== sub landing { use vars qw/$server $sock $port @data $whois/; $server = ""; $port = "43"; my $target = ""; $sock = IO::Socket::INET->new(PeerAddr=>$server,PeerPort=>$port,Prot +o=>'tcp'); print $sock $target,"\r\n"; @data = <$sock>; undef($sock); my $i = 1; my @chkReport; my @lblReport; for (@data) { $chkReport[$i] = $frame->Checkbutton() ->place(-x => 0, -y => $nHOffset * ($i + 1)); #== $lblReport[$i] = $frame->Label(-text => $_) ->place(-x => $nVOffset, -y => $nHOffset * ($i + 1)); #== $i++; } } my $bLanding = $wMain->Button(-text => 'Parse', -command => sub{landing}) ->place(-x => 500, -y => 0); #== MainLoop;
Nonsense I know about:

The "#==" that appears at the end of some lines is because of a peculiarity in OpenIDE, which doesn't always seem to know when to stop showing things in purple. This solves that problem.

Part of the code uses Hungarian notation and part doesn't. This is because I have picked up some of the code from Yet another whois client (only in perl) and elsewhere, and want to get it working before I add mistakes by renaming variables.

I have hard coded inputs (a) to reduce the length of the code, and (b) to reduce the chance of bugs. This won't happen in the final version.

I have tried:

Canvas instead of frame. The docs I have read indicate that frame isn't scrollable, but I also get the impression that Pane is the way around this.

Update everywhere I can imagine it making a difference.

Outputting each line as the "text" attribute of the checkbox.

Feel free to go all perlmonks on me or attempt a Socratic dialogue. I'm trying to learn. Also, if & when I get it working (no promises on time), is this the sort of thing other monks would like me to post?

TIA & regards,

John Davies

Replies are listed 'Best First'.
Re: Scrolling data in Tk
by jdporter (Canon) on Nov 20, 2007 at 12:45 UTC

    It appears to be from your use of place, rather than pack or grid, to position the buttons and labels within the scrolled frame. I guess, by you taking control of the placement geometry, the scrolled geometry manager doesn't have enough information to know when to enable the scrollbars.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight
      Ouch. A quick experiment with pack gets the scrollbar working, as you promised. The output looks ghastly, but that's because it was a quick experiment & I don't grok pack. I was scared of this sort of ambush when I asked about it in Tk: pack, grid or place?, but the closest anyone came was g0n's warning about resizing.

      Thank you for this - off to the manuals!


      John Davies

        In this case it's probably much easier to convert to grid, rather than, pack, since you're already in effect faking your own grid layout.

        for (@data) { $chkReport[$i] = $frame ->Checkbutton() ->grid( -column => 0, -row => $i ); #== $lblReport[$i] = $frame ->Label( -text => $_ ) ->grid( -column => 1, -row => $i ); #== $i++; }
        A word spoken in Mind will reach its own level, in the objective world, by its own weight
Re: Scrolling data in Tk
by zentara (Archbishop) on Nov 20, 2007 at 13:31 UTC
    You are right about the Scrolled Pane working better than the Scrolled Frame. Actually, the thing you probably want to do is put a Frame (packed so that it expands and fills) into a Scrolled Pane. The Scrolled Pane should take care of adjusting it's scrollbars to the new frame size, as you add widgets to the frame.
    #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Pane; my $count = 10; my $Frame; my $mw = tkinit; my $pane = $mw->Scrolled( 'Pane', -scrollbars => 'e', ) ->pack( -expand => 1, -fill => 'both' ); $mw->Button( -text => 'Refresh', -command => \&Refresh, )->pack; Refresh(); MainLoop; sub Refresh { my @a; $count +=10; for ( my $i = 0 ; $i < $count ; $i++ ) { push( @a, int( rand(100) +) ) } DisplayCheckButtons( $pane, @a ); } sub DisplayCheckButtons { my ( $parent, @names ) = @_; $Frame->destroy if $Frame; $Frame = $parent->Frame->pack( -expand => 1, -fill => 'both' ); map { $Frame->Checkbutton( -text => $_ )->pack } @names; }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://651906]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (8)
As of 2017-02-25 19:28 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (368 votes). Check out past polls.