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

I am using tk module to build a checklist for user to choose. I am totally beginner to this module. Currently the checklist created is all in the same series column, since it will be a long list, any idea how could I separate few of the options to another column? Also, any idea how to align those text to the left while checkbox to the right? To display it cleanly and neatly.

#!/usr/bin/perl use Tk; $main = MainWindow->new(); $label = $main->Label(-text => "Presence Check"); $label->pack(); $frame = $main->Frame(-relief=>"groove", -borderwidth=>2); #$frame = $main->Frame(-relief=>"groove", -borderwidth=>2)->pack(-side + => 'top', -expand => 1, -fill =>'both'); #$frame = $main->Frame->pack(-side => 'left', -fill => 'x'); $check1 = $frame->Checkbutton(-text=>"Document A (docx, pdf)", -variable=>\$a, -onvalue=>"APRESENT", -offvalue=>"AABSENT"); #$check1->pack(-side=>"top"); $check2 = $frame->Checkbutton(-text=>"Document B (xlsx)", -variable=>\$b, -onvalue=>"BPRESENT", -offvalue=>"BABSENT"); $check2->pack(-side=>"top"); $check3 = $frame->Checkbutton(-text=>"C specification", -variable=>\$c, -onvalue=>"CPRESENT", -offvalue=>"CABSENT"); $check3->pack(-side=>"top"); $check4 = $frame->Checkbutton(-text=>"A-Specification", -variable=>\$aspec, -onvalue=>"ASPECPRESENT", -offvalue=>"ASPECSABSENT"); $check4->pack(-side=>"top"); $check5 = $frame->Checkbutton(-text=>"Important Report", -variable=>\$report, -onvalue=>"REPORTPRESENT", -offvalue=>"REPORTSABSENT"); $check5->pack(-side=>"top"); $check6 = $frame->Checkbutton(-text=>"Handbook", -variable=>\$handbook, -onvalue=>"HANDBOOKPRESENT", -offvalue=>"HANDBOOKABSENT"); $check6->pack(-side=>"top"); $check7 = $frame->Checkbutton(-text=>"Data Spreadsheet", -variable=>\$dataxls, -onvalue=>"DATAPRESENT", -offvalue=>"DATAABSENT"); $check7->pack(-side=>"top"); $check8 = $frame->Checkbutton(-text=>"D file", -variable=>\$dfile, -onvalue=>"DFILEPRESENT", -offvalue=>"DFILEABSENT"); $check8->pack(-side=>"top"); $check10 = $frame->Checkbutton(-text=>"xx doc", -variable=>\$xxdoc, -onvalue=>"XXDOCPRESENT", -offvalue=>"XXDOCABSENT"); $check10->pack(-side=>"top"); $check18 = $frame->Checkbutton(-text=>"yy Doc", -variable=>\$yydoc, -onvalue=>"YYDOCPRESENT", -offvalue=>"YYDOCABSENT"); $check18->pack(-side=>"top"); $frame->pack(); $button = $main->Button(-text => "Exit", -command => \&exit_button); $button->pack(); MainLoop(); sub exit_button { print "$a $b $c $aspec $report $handbook $dataxls $dfile $xxdoc $yydoc + \n"; #print "$rv\n"; exit, }

Replies are listed 'Best First'.
Re: PERL tk module handling
by stefbv (Priest) on Apr 19, 2020 at 10:10 UTC

    Use different frames to separate widgets in columns when you are using pack, or use other geometry managers like grid, frame or place. A good source of inspiration is the widget demo script that comes with TK (enter 'widget' in the console).

    The anchor option is for alignment.

    use 5.010; # for say use strict; use warnings; use Tk; my $main = MainWindow->new(); my $label = $main->Label( -text => "Presence Check" )->pack(); my $opt_ft = [qw/-side top -expand 1 -fill both/]; my $opt_flr = [qw/-side left -expand 1 -fill both/]; my $opt_fb = [qw/-side bottom -expand 1 -fill both/]; my $opt_c = [qw/-side top -pady 2 -anchor w/]; my $fr_top = $main->Frame()->pack(@$opt_ft); my $fr_top_l = $fr_top->Frame()->pack(@$opt_flr); my $fr_top_r = $fr_top->Frame()->pack(@$opt_flr); my $fr_bot = $main->Frame()->pack(@$opt_fb); my ( $vbutton1, $vbutton2, $vbutton3 ) = ( 'OFF', 'ON', 'OFF' ); my $b1 = [ [ 'button1', 'button 1', \$vbutton1, 'OFF', 'ON' ], [ 'button2', 'button 2', \$vbutton2, 'OFF', 'ON' ], [ 'button3', 'button 3', \$vbutton3, 'OFF', 'ON' ], ]; foreach my $btn (@$b1) { $fr_top_l->Checkbutton( -text => $btn->[1], -variable => \$btn->[2], -offvalue => $btn->[3], -onvalue => $btn->[4], )->pack(@$opt_c); } my ( $vbutton4, $vbutton5 ) = ( 'ON', 'OFF' ); my $b2 = [ [ 'button4', 'button 4', \$vbutton4, 'OFF', 'ON' ], [ 'button5', 'button 5', \$vbutton5, 'OFF', 'ON' ], ]; foreach my $btn (@$b2) { $fr_top_r->Checkbutton( -text => $btn->[1], -variable => \$btn->[2], -offvalue => $btn->[3], -onvalue => $btn->[4], )->pack(@$opt_c); } my $button = $fr_bot->Button( -text => "Exit", -command => \&exit_button )->pack(@$opt_ft); MainLoop(); sub exit_button { foreach my $btn (@$b1) { say "- $btn->[0]: $btn->[1] -> ${$btn->[2]}"; } foreach my $btn (@$b2) { say "- $btn->[0]: $btn->[1] -> ${$btn->[2]}"; } $main->destroy; }

    Regards, Stefan.

Re: PERL tk module handling
by kcott (Archbishop) on Apr 19, 2020 at 12:56 UTC

    G'day michael99,

    I can't tell exactly the layout you're aiming for. A little bit of simple ASCII art can help to explain what you want. For instance, you currently have something along these lines:

    +--+ |A1| |A2| |A3| |B1| |C1| |C2| +--+

    Do any of these look like what you ultimately want?

    +--------+ +--------+ +-----+ |A1|A2|A3| |A1|B1|C1| |A1|B1| |B1| | | |A2| |C2| |A2|C1| |C1|C2| | |A3| | | |A3|C2| +--------+ +--------+ +-----+

    Here's a couple of tentative suggestions:

    • Perhaps changing the geometry manager from Tk::pack to Tk::grid might be helpful.
    • As you talk about the checkbuttons being in columns, perhaps Tk::HList would be a useful option. If you run the widget demo — in case you don't know, that's just widget from the command line — you'll find an example (GUI demo and code) of doing this. It's under:
        Tix Widgets
          ...
          Multicolumn listbox ...

    With more information from you, better suggestions may present themselves.

    — Ken

Re: PERL tk module handling
by AnomalousMonk (Archbishop) on Apr 19, 2020 at 13:36 UTC

    Here's another frames-within-frames approach.
    tk_multi_check_2.pl:


    Give a man a fish:  <%-{-{-{-<

Re: PERL tk module handling
by tybalt89 (Monsignor) on Apr 19, 2020 at 17:23 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11115774 use warnings; use Tk; my $mw = MainWindow->new; $mw->geometry( '+500+300' ); my $list = $mw->Frame->pack; $mw->Button(-text => 'Exit', -font => 24, -command => sub {$mw->destroy}, )->pack(-fill => 'x'); # FIXME - of course, change to list of your own data... my @listdata = map { text => "Document A$_ (docx, pdf)", var => \$a, on => "APRESENT", off => "AABSENT" }, 1 .. 25; my $maxrows = 10; my $row = 1; my $col = 1; for my $datum ( @listdata ) { $list->Checkbutton( -variable => $datum->{var}, -onvalue => $datum->{on}, -offvalue => $datum->{off}, )->grid(-row => $row, -column => $col + 1); $list->Label( -text => $datum->{text}, -font => 24, )->grid(-row => $row, -column => $col, -sticky => 'e'); if( ++$row > $maxrows ) { $row = 1; $col += 2; } } MainLoop;
Re: PERL tk module handling (Tk::CheckbuttonGroup)
by Anonymous Monk on Apr 19, 2020 at 10:14 UTC