Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Perl/Tk scrolling question...

by jdtoronto (Prior)
on Apr 12, 2007 at 20:15 UTC ( #609737=perlquestion: print w/ replies, xml ) Need Help??
jdtoronto has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed monks,

I have Perl/Tk code which produces a window something like a day-timer week at a view page. Across the top I have the days of the week, down the left hand side time of day in 10 or 15 minute increments. Now comes my problem.

I have scroll bars on both X and Y axes. But when I scroll horizontally I want the days of the week to scroll with the body (the times to remain visble), but when I scroll vertically I want the days of the week to stay visible whilst the times scroll with the body.

The body of the window consists merely of a huge collection of buttons, one for each time slot for each day of the week.

How do I do it?

jdtoronto

Comment on Perl/Tk scrolling question...
Re: Perl/Tk scrolling question...
by jdporter (Canon) on Apr 12, 2007 at 20:40 UTC

    Not that I've tried it — and my experience with Tk leads me to intuit that it won't work out as cleanly as it should — but it sounds to me like you want two scrollables, one inside the other. The outer scrollable would only scroll horizontally. The thing it contains (a Pane, I suppose) would contain a frame at the top, non-scrolling, and a scrollable below that which scrolls vertically.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight
Re: Perl/Tk scrolling question...
by graff (Chancellor) on Apr 13, 2007 at 00:18 UTC
    So if the user scrolls horizontally to the "middle" of the day-of-week range, then scrolls vertically to the "middle" of the time-of-day range, both the day-of-week labels and time-of-week labels need to still be visible, right?

    For that to work, I think you actually need three scrolling windows:

    • a "column headings" window that shows the day-of-week labels (has a height of one line), and only scrolls left-to-right;

    • a "row headings" window that shows the time-of-day labels (has a width of 5 characters: HH:MM), and only scrolls up-and-down;

    • the data grid table of 7 columns by however many rows (each cell is as big as you think necessary), and scrolls in all directions.

    I don't have any specific coding examples handy, but I do remember that there's a way to set up callbacks on the scrollbars for a given scrolling window. The idea is that the scrollbars for the grid window will invoke call backs that will trigger an equivalent amount of scrolling in the x dimension on the column-heading window, as well as an equivalent amount of y-dimension scrolling on the row-heading window.

    Shouldn't be too hard, once you find the right Tk man page (probably Tk::Scrollbar). Good luck with that.

    (update: fixed the link and a spelling error, and wanted to add that you probably want to limit the number of visible scrollbars for all those scrolling windows -- display just one scrollbar for each direction -- and bear in mind that Tk lets the user to a "grab-and-drag" to scroll the grid window.)

Re: Perl/Tk scrolling question...
by zentara (Archbishop) on Apr 13, 2007 at 11:43 UTC
    If I understand your desire correctly, you want linked scrollbars. Here is a canvas example, you can probably make it work on other widgets. I use it in my tvguide program.
    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = new MainWindow(); $mw->geometry("600x400+200+200"); #for xscroll, must be packed before midframe to be visible my $botframe = $mw->Frame(-bg=>'grey45') ->pack(-fill=>'x',-side=>'bottom'); my $midframe = $mw->Frame(-bg=>'grey45')->pack(); my $midframel = $midframe->Frame(-bg=>'grey45') ->pack(-side=>'left',-expand=>1,-fill=>'y'); my $midframer = $midframe->Frame(-bg=>'grey45') ->pack(-side=>'right'); my $num_channels = 40; my $canvasp; my $canvast = $midframer->Canvas( -bg =>'pale goldenrod', -width=>2400, -height=>25, #need to set scrollregion with a bit extra to ensure #endpoint accuracy. See xscrollit sub -scrollregion=>[-10,0,7450,25], -xscrollincrement => 1, )->pack(-side=>'top'); #for canvasp and yscroll my $midframer1 = $midframer->Frame(-bg=>'grey45') ->pack(-side=>'top'); my $yscroll = $midframer1->Scrollbar( -orient => 'vertical', -command => \&yscrollit, -troughcolor =>'grey45', -activebackground =>'lightseagreen', -background => 'lightseagreen', )->pack(-side=>'right',-fill=>'y'); my $canvasxsd = $botframe->Canvas( #dummy filler -bg =>'grey45', -width=>75, -height=>25, -borderwidth=>0, ) ->pack(-side=>'left'); my $xscroll = $botframe->Scrollbar( -orient => 'horizontal', -command => \&xscrollit , -troughcolor =>'grey45', -activebackground =>'lightseagreen', -background => 'lightseagreen', )->pack(-side=>'right', -fill=>'x',-expand =>1); print "$xscroll\n"; $canvasp = $midframer1->Canvas( -bg =>'lightsteelblue', -width=>2400, -height=> 50 * $num_channels, -scrollregion=>[-10,0,7450,(33 * $num_channels)], -xscrollincrement => 1, -yscrollincrement => 1, -xscrollcommand => [ 'set', $xscroll ], -yscrollcommand => [ 'set', $yscroll ], ) ->pack(-side=>'left');#,-fill=>'both'); my $canvasd = $midframel->Canvas( #top of left frame dummy filler -bg =>'grey45', -width=>75, -height=>25, -borderwidth =>0, )->pack(-side=>'top'); my $canvass = $midframel->Canvas( #left frame canvas -bg =>'lightseagreen', -width=>75, -height=> 50 * $num_channels, -scrollregion=>[0,0,75,(33 * $num_channels)], -yscrollincrement => 1, ) ->pack(-side=>'top'); #fill in some sample data to see scrolling action for( 1 .. 33 * $num_channels){ $canvass->createText(38, 10 + $_ * 33, -text => "C $_" , ); } #set up top frame canvas... a timeline for(0..7200){ if( $_ % 300 == 0){ my $time = $_ / 300; my $padded = ("0" x (2-length( $time ))).$time; $canvast->createLine($_,0,$_,12,-width=> 4,-tags=>['tick'] ); $canvast->createText($_, 20, -text=> "$padded:00",-tags=>['ti +ck'] ); }elsif( $_ % 150 == 0){ my $time = ($_ - 150) / 300; my $padded = ("0" x (2-length( $time ))).$time; $canvast->createLine($_,0,$_,10,-width => 2,-tags=>['tick']); $canvast->createText($_, 20, -text=> "$padded:30",-tags=>['ti +ck'] ); }elsif( $_ % 75 == 0){ $canvast->createLine($_,0,$_,6,-width => 1, -tags=>['tick']); } } #set up main frame canvas for(0..7200){ $canvasp->createText($_ * 20, 5 + $_ * 20, -text=> "Test $_", -tags=>['data'] ); } #--------------------------------------------------------------- MainLoop; ################################################################ ###################################################################### +# sub xscrollit{ my $fraction = $_[1]; $canvast->xviewMoveto($fraction); $canvasp->xviewMoveto($fraction); } ###################################################################### sub yscrollit{ my $fraction = $_[1]; $canvass->yviewMoveto($fraction); $canvasp->yviewMoveto($fraction); } ####################################################################

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

      Thank you once again! It does EXACTLY what I need. I had it about half worked out before I saw your response, but now it is fully worked out.

      Why can't I give you more than one vote?

      jdtoronto

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://609737]
Approved by Joost
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2015-07-05 13:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (67 votes), past polls