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

Hello PerlMonks,

I am back at Perl Tk again. I'm creating an order like logfile from MENU.txt; however, I came to an abrupt end because I do not know how to do many the following - it's not shocking for me to come to an abrupt end after failing and trying new stuff to make it work. Anyhow, I am creating this GUI to get some experience in handling some tasks below. If you have an idea how to improve please write comments so I can follow the code; I learn by trying new stuff and comments help me a lot ;-)

Formatting challenges ( it tried and just could get it; I haven't giving up on formatting yet)

1) How to make checkbox stay lined up one below the other regardless of the length of the text string?

1a) How to format Checkbox text to wrap around the next line below without moving around the checkbox?

2) How to make left frame to meet right with a small line going down separation both?

Some additional functionality ; these I need help because I am not sure how to do any of these

3) After first checkbox selected, how to add an additional pop up check box?

4) How to add a file browser button to left size when selecting checks.txt file and select file from a menu and save/show the selection on the GUI? my file browser sort of works but requires a lot of work

5) How to add a button/code (side => right) to email recipients in a list of the output or pointer to output from the GUI

Special frame to add comments below checkboxes && save it to log file

6) How to add frame (frm_frame) on right side below checkboxes to allow user to add comments with a title=> "Special Notes"? then save it all to a logfile

#!/usr/bin/perl # This program will select items via checkbox # This program will then save these selections to a log file it create +s # This is figuring out how frames work, checkbox, radiobutton, file br +owser. # Validates input -> later # March 20 2022 use strict; use warnings; use Tk; use Tk::Checkbutton; use Tk::Radiobutton; use Tk::Pane; use Tk::BrowseEntry; #my $file = "expenses"; #add validation if file exists. #-----------------FH open/close------------------# #open Log file here ....I think it is here to get tail -f of final out +put #---------------Declare vars---------------------# my ($var1,$var2,$var3,$var4); my $current_file=(); #--------------------Frames geometries-----------# my $mw = MainWindow->new(); $mw->geometry("1000x500"); $mw->title("Check using GUI"); #-----------------Frames-----------------------# my $main_frame = $mw->Frame()->pack( -side => 'top', - fill => 'x' ); my $top_frame = $mw->Frame( -background => 'light green' )->pack( -side => 'top', +-fill => 'x' ); my $left_frame = $mw->Frame( -background => 'gray' , -width => 45)->pack( -side => +'left', -fill => 'y' ); my $right_frame = $mw->Frame( -background => 'white', -foreground => 'white' )->pack +( -side => 'right', -fill => 'y' ); # This is the Special Notes area for user to add text my $frm_frame = $mw->Frame( -background => 'light blue' )->pack( -side => 'right' +, -fill => 'x'); #---------------TOP Widget-------------------------# $top_frame->Label( -text => "Bank statement Checks", -background => 'light green' ) ->pack( -side => 'top' ); #------------LEFT wedget-------------------------# $left_frame->Label( -text => 'Checks Selection', -background => 'white', -width => 45 )->pack( -side => 'top', -fill => 'both' ); #-----------adding file browser to chose the Checks.txt file------- +------# our $mw = MainWindow->new; $mw->configure(-title=> "File Browser"); my $menu_f = $mw->Frame()->pack(-side=>'top',-fill=>'x'); my $menu_file = $menu_f->Menubutton (-text=>'Select File Browser',-tearoff=>'false') ->pack(-side=>'left'); $menu_file->command(-label=>'...', -command=> \&open_txt); # This opens txt files where ch +ecks written with amounts # GRRR! -command isn't working for me h +ere, where did I go wrong??!!! #------------Right checkButtons------------------------# my $right_text; my ($check1, $check2, $check3, $check4); $check1= $right_frame->Checkbutton( -text => "Confirm check was used for home to school travel, books, + meals", -onvalue => 1, -background => 'white', -variable => \$var1, )->pack(); $check2= $right_frame->Checkbutton( -text => "Discuss check usage are only for school expenditures", -onvalue => 1, -background => 'white', -variable => \$var2, )->pack(); $check3= $right_frame->Checkbutton( -text => "Archive the checks that are to come visit home segregate +d from other travel from home to school", -onvalue => 1, -background => 'white', -variable => \$var3, )->pack(); #### HOW to add another popup Checkbox when $check3 is selecte +d; is it Parents HOME or Grand Parent's home if ($var3 == 1 ){ ## how to get logic to recognized $check3 is + selected?? then opo up with new additional checkbox selection is it +== 1 or eq true??? my $check20= my $frm_frame= $mw ->Frame(); my $check_travel = my $frm_name ->Label ( -text => "Check from sch +ool to home travel"); my $ent = $frm_name -> Entry(); # This is not right either!! + I've tried many things unsuccessful ...Need to ask for help! } $check4= $right_frame->Checkbutton( -text => "Confirm there were no Check errors/corrupted files durin +g audit", -onvalue => 1, -background => 'white', -variable => \$var4, )->pack(); #---------- Exit Button -----------------------# my $left_text; my $exitButton= $left_frame->Button( -text => "Done" , -command => sub { exit } )->pack( -side => 'bottom' , -fill =>'both', -expand =>1); #------------Enter button && save to Log file-------------------# my $executeButton = $left_frame->Button( -text => "Enter" , -command => sub { Echo_to_Log($left_text);} )->pack( -side => 'bottom', -fill => 'both' , -expand =>1); # C +aputure ALL of checkboxes and Path to files, # shoudl it be "left_text" && $ri +ght_text(create if so)?How to do this?jj #------------format Enter and Done buttons ----# $left_text = $left_frame->Text( -height => 30, -width => 30 , )->pack( -side => 'left' , -fill => 'both', -expand =>1 ); #--------------Format right buttons -----# $right_text= $right_frame->Text( -height => 30, -width => 70, )->pack( -side => 'right' , -fill => 'both', -expand =>1 ); MainLoop; sub open_txt { my @types = (["txt files", [qw/.txt /]], ["All files", '*'], ); $current_file= $mw->getOpenFile(-filetypes => \@types); print "$current_file\n"; } sub Echo_to_log { # let's put all the selections into a Logfile. I am not sure if a -t +ail -f will work here because I want only selected windows }
  • Comment on Perl Tk, how to get File Browser, capture output to a Log file and format my checkboxes
  • Download Code

Replies are listed 'Best First'.
Re: Perl Tk, how to get File Browser, capture output to a Log file and format my checkboxes
by kcott (Archbishop) on Mar 22, 2022 at 07:06 UTC

    G'day perlynewby,

    Some general pointers:

    • Have the Tk documentation open and refer to it often when coding.
    • Check the Widget Demo (type widget on the command line) for code that does the sort of thing you want; then adapt for your specific needs.
    • Follow the "Clone repository" link and look for code in t/ (test) directories. This may have something similar to what you need.
    • Avoid monolithic scripts. Break you code into manageable units (subroutines). Pass references to variables. Declaring lexical variables with file scope is (almost) the same as using global variables: you'll encounter much the same problems.
    • Post multiple questions here, each targeting a specific issue. You've asked about checkboxes, file browers, emailing, logging and so on: some people may not have time to answer all; some may not wish to work through everything and pick out the bits they can answer; and others may find a huge wall of questions too daunting and just move on.

    For your "Formatting challenges" questions, I suspect your main problem here is the exclusive use of the Tk::pack geometry manager. Laying out the frames of your GUI with pack() is often a good way to go. When lining up widgets within those frames, Tk::grid is possibly a better choice. See the "Tk Geometry Management" section for other options.

    For your other questions, it wasn't clear whether you were asking how to do something or how to position a widget (e.g. "on right side below checkboxes"). I've provided tentative answers based on "how to do" and not "how to position".

    • "additional pop up check box" — it's unclear what you're looking for here: pop-up menu?; dialog box?; Tk::Toplevel?; something else? I'd guess you'd want the -command option of Tk::Checkbutton.
    • "add a file browser button" — see "Common Dialogs" in the Widget Demo.
    • "add a button/code ... to email recipients"Tk::Button with the -command option.
    • 'add frame ... to allow user to add comments with a title=> "Special Notes"?'Tk::LabFrame with -label => 'Special Notes'; Tk::Text for the comments.

    Some final notes:

    • Please provide error messages or a better description of problems. Things like "my file browser sort of works but requires a lot of work" and "GRRR! -command isn't working for me here" do not help.
    • A simple bit of ASCII-art is often a much better way to convey a layout than a prosaic description.
    • Please check the code you are posting. In your OP, you have the following which looks like a major problem waiting to happen:
      my $mw = MainWindow->new(); ... our $mw = MainWindow->new;

    — Ken

      Hello all

      On a side note, I noticed that I had 4 more replies to this post and those are no longer visible to me in the chatterbox, would you know why or how that happens? I need to avoid that.

      Any ideas on how to retrieve those prior messages in chatterbox so I can finish reading these messages from other contributors?

      Ken and et al, As always I appreciate the help and comments and will follow your suggestions while posting, writing my code, and having Perl references open.

      Thanks so much!

        If you mean private messages in the Message Inbox instead of public Chatterbox, you should be able to click on "And 4 more" under the message list in the Chatterbox. It should display the Inbox where you can view older messages, delete or archive them, etc.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Perl Tk, how to get File Browser, capture output to a Log file and format my checkboxes
by tybalt89 (Monsignor) on Mar 22, 2022 at 12:22 UTC

    See the NOTE comments for possible solutions to some of your n) issues.

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11142273 use warnings; use Tk; my $additionalcheckbutton = 0; my @checkbuttonlabels = split /\n/, <<END; one two very long text entry for test purposes three for more info align problem four extra check END my @values = (0) x @checkbuttonlabels; my $wantspecial = 0; my $notes; my $mw = MainWindow->new; $mw->geometry('+700+400'); $mw->Button(-text => 'Exit', -command => sub{$mw->destroy}, )->pack(-side => 'bottom', -fill => 'x'); my $leftframe = $mw->Frame()->pack(-side => 'left'); my $n = 0; my @cbs = map { $leftframe->Checkbutton( -text => s/.{20}\K /\n/gr, # NOTE 1a) wrap if text too long -anchor => 'w', # NOTE 1) align buttons with -fill x -variable => \$values[$n++], -command => \&addextra, )->pack(-fill => 'x'); } @checkbuttonlabels; $mw->Frame(-bg => 'blue', -width => 3, # NOTE 2) separation line )->pack(-side => 'left', -fill => 'y'); my $rightframe = $mw->Frame()->pack(-side => 'left'); $rightframe->Label(-text => "The Right Side\nFrame", )->pack; $rightframe->Checkbutton(-text => "Special Notes?", -variable => \$wantspecial, -command => \&specialnotes, )->pack; my $subframe = $rightframe->Frame->pack; $subframe->Label(-text => 'Special Notes', -bg => 'blue', -fg => 'whit +e',, )->pack(-fill => 'x'); $notes = $subframe->Text()->pack; $_->packForget for @cbs[4, -1], $subframe; # NOTE initially not visibl +e MainLoop; -M $0 < 0 and exec $0; # for testing FIXME sub specialnotes # pack/packForget special notes { if( $wantspecial ) { $subframe->pack; $notes->delete('1.0' => 'end'); } else { $subframe->packForget; } } sub addextra { # NOTE 3) add additional checkbox $additionalcheckbutton++ or $cbs[-1]->pack(-fill => 'x'); if( $values[3] ) # NOTE 6) addextra for checkbutton three { $cbs[4]->pack(-fill => 'x', -after => $cbs[3] ); } else { $cbs[4]->packForget; } }

    Uses pack/packForget for widgets that are transitory.

      Replace

      s/.{20}\K /\n/gr

      with

      s/(.{20}) /$1\n/gr

      if you are running with an old perl.

        Hello

        Yes, I am using and old perl version; it's the only one available to me. This is current perl -v, "This is perl, v5.6.1 built for i686-linux-thread-multi"

        So this perl version did not like the replacement s/(.{20}) /$1\n/gr , any other idea to satisfy this wrap around text ?

        I really would like to see your wrap around text code work.

        I was super busy at work today and feeling under the weather but I will post some updates to the GUI.

        Right now, only thing I can see having an issue is capturing the selection into a log file

        And adding a email utility with output of the selections.

        This is what I think the GUI to look

        A= Left side frame with ( about 4) long texts with a corresponding checkbox.

        B= 2 files chosen by using a file browser to select certain bank monthly statements.

        C= Lower frame is a "Special Note" selection that opens up for user input.

        D= Email button which sents an automated email with output of GUI to, say, daughter.

        diagram isn't working out; I tried. Sorry.

        xxxxxxxxxxxxx

        x A \t\t x \t\t B x

        xxxxxxxxxxxxxx

        x \t\t C \t\t x

        xxxxxxxxxxxxx

        x \t\t D \t\t x

        xxxxxxxxxxxxx

        Thanks for the help on formatting the checkboxes, adding the note pad too, and adding an extra checkbox