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

Folks,

I am creating a small lite weight gui to enter data into a text file. This is more of a learning experience then anything. I currently have Perl/tk books on route; however, I am using the Tkx library in Activestate. I have found a number Tk examples to clear the content of a textbox; however, I really cannot find what I am looking for for Tkx - to be honest not sure what I need to look for.

I need some help with my clear sub

#!/usr/bin/perl use Tkx; Tkx::wm_title(".", "CSV Book Entry"); Tkx::ttk__frame(".c", -padding => "3 3 12 12"); Tkx::grid( ".c", -column => 0, -row => 0, -sticky => "nwes"); Tkx::grid_columnconfigure( ".", 0, -weight => 1); Tkx::grid_rowconfigure(".", 0, -weight => 1); #Tkx::ttk__entry(".c.feet", -width => 7, -textvariable => \$feet); #Tkx::grid(".c.feet", -column => 2, -row => 1, -sticky => "we"); #Tkx::ttk__label(".c.meters", -textvariable => \$meters); #Tkx::grid(".c.meters", -column => 2, -row => 2, -sticky => "we"); #Tkx::ttk__button(".c.calc", -text => "Calculate", -command => sub {ca +lculate();}); #Tkx::grid(".c.calc", -column => 3, -row => 3, -sticky => "w"); Tkx::ttk__entry(".c.txtbox_file_name", -width => 25, -textvariable => +\$txtbox_file_name); Tkx::grid(".c.txtbox_file_name", -column => 2, -row => 1, -sticky => " +e"); Tkx::ttk__entry(".c.txtbox_title", -width => 25, -textvariable => \$tx +tbox_title); Tkx::grid(".c.txtbox_title", -column => 2, -row => 2, -sticky => "e"); Tkx::ttk__entry(".c.txtbox_author", -width => 25, -textvariable => \$t +xtbox_author); Tkx::grid(".c.txtbox_author", -column => 2, -row => 3, -sticky => "e") +; Tkx::ttk__entry(".c.txtbox_series", -width => 25, -textvariable => \$t +xtbox_series); Tkx::grid(".c.txtbox_series", -column => 2, -row => 4, -sticky => "e") +; Tkx::ttk__entry(".c.txtbox_isbn", -width => 25, -textvariable => \$txt +box_isbn); Tkx::grid(".c.txtbox_isbn", -column => 2, -row => 5, -sticky => "e"); Tkx::ttk__button(".c.enter", -text => "Enter", -command => sub {enter( +);}); Tkx::grid(".c.enter", -column => 1, -row => 6, -sticky => "w"); Tkx::ttk__button(".c.clear", -text => "Clear", -command => sub {clear( +);}); Tkx::grid(".c.clear", -column => 2, -row => 6, -sticky => "we"); Tkx::grid( Tkx::ttk__label(".c.flbl", -text => "FILENAME:"), -column = +> 1, -row => 1, -sticky => "w"); Tkx::grid( Tkx::ttk__label(".c.islbl", -text => "TITLE:"), -column => +1, -row => 2, -sticky => "W"); Tkx::grid( Tkx::ttk__label(".c.mlbl", -text => "AUTHOR:"), -column => +1, -row => 3, -sticky => "w"); Tkx::grid( Tkx::ttk__label(".c.slbl", -text => "SERIES:"), -column => + 1, -row => 4, -sticky => "W"); Tkx::grid( Tkx::ttk__label(".c.isbnlbl", -text => "ISBN:"), -column => + 1, -row => 5, -sticky => "W"); sub enter { $filename = 'bookdb.txt'; open($WRITEFILE, '>>', $filename) or die; #Maybe add values into array??? #@data = qw($txtbox_file_name $txtbox_title $txtbox_author $txtbox_s +eries $txtbox_isbn); $data = "$txtbox_file_name,$txtbox_title,$txtbox_author,$txtbox_seri +es,$txtbox_isbn\n"; print $WRITEFILE "$data"; close $WRITEFILE; } # sub clear { # delete our $txtbox_file_name; # } Tkx::MainLoop();

Thank you much appreciated

Replies are listed 'Best First'.
Re: Tkx and clear a textbox content
by huck (Prior) on Aug 21, 2017 at 15:22 UTC

    is this all you want?

    sub clear { $txtbox_file_name=''; $txtbox_title=''; $txtbox_author=''; $txtbox_series=''; $txtbox_isbn=''; }

      Yes that did it.. cleared the text in the boxes... Thank you.

Re: Tkx and clear a textbox content
by kcott (Archbishop) on Aug 22, 2017 at 07:57 UTC

    G'day jasonwolf,

    "This is more of a learning experience then anything."

    Well, we all have to start somewhere. There are a number of problems with this code: I've highlighted some of these in my response to zentara's question.

    Although this is GUI code, it's still Perl code, and you should write it in the same way as you would other Perl code. Always start with

    use strict; use warnings;

    Don't write a monolithic script; instead adopt a modular approach. Use lexical variables in the smallest scope possible (this includes filehandles — see open).

    The Tkx documentation has links to tutorials which you should find useful. I've read all of these and am aware of some conflicts with the advice given. As a general rule, where there appear to be discrepancies, I'd recommend following the Perl/CPAN advice in preference to the Tcl advice. And, of course, when in doubt, come back and ask us about it.

    — Ken

      I am still trying to grasp 'use strict'. My code has a hard time running; however, I suspect that due to my scope with functions and global/private. I am not a programmer by trade, only self-taught out of necessity.

        I'll reply to both of your posts[1,2] here. There's a certain amount of overlap in the information: this will keep it all in one place.

        "I am still trying to grasp 'use strict'."

        Without knowing what aspect of that you're having problems grasping, it's somewhat difficult to give direct help. I'd suggest reading perlintro; follow the links therein for more detailed information; then, if you're still having difficulties, ask a specific question or, at least, tell us what the problem area is (maybe post that as separate question unless its specifically Tkx-related).

        "My code has a hard time running; ..."

        Sorry, that's unclear. Slow to start? Unresponsive? Something else?

        "... due to my scope with functions and global/private."

        I mentioned "scope" in both[3,4] of my earlier replies. I've addressed this more fully below.

        "I will be honest, I am not sure what is the correct way to program with the TCL/TK format as you point out. I am only using the Example from the TKDoc link http://www.tkdocs.com/tutorial/firstexample.html"

        [Aside: Please provide actual links, rather than the URL as text. This allows you to test it when previewing; and it's easier for us to just follow a link instead of having to the select text, copy it, paste into address bar, ... See "What shortcuts can I use for linking to other information?" if you don't know how to do this.]

        If you look at http://www.tkdocs.com/tutorial/firstexample.html, just below the sample code, you'll see the heading, A Note on Coding Style. The text that follows, includes:

        "... a very direct coding style, rather than wrapping up most of our code in procedures, modules, objects, classes and so on."

        So, in essence, it's showing you how to use Tcl/Tk code; it's not showing you the best way to write that code in Perl.

        The following is a working and tested example, based loosely on your original code, showing how you could write it using lexical variables in minimal scope. There are no variables with global scope. The code consists of discrete subroutines that perform separate functions: &build_gui knows nothing about $entries; &write_entries knows nothing about $mw; the variables modified by &clear_entries are passed to that subroutine in its argument list; and so on.

        #!/usr/bin/env perl -l use strict; use warnings; use Tkx; { my $mw = Tkx::widget->new("."); build_gui($mw); } Tkx::MainLoop(); sub build_gui { my ($mw) = @_; configure_gui($mw); my $frame = build_framework($mw); populate_framework($frame); return; } sub configure_gui { my ($mw) = @_; $mw->g_wm_title('Entry Example'); $mw->g_wm_minsize(300, 200); return; } sub build_framework { my ($mw) = @_; my $frame = $mw->new_ttk__frame(-padding => '10 10 10 10'); $frame->g_grid(-column => 0, -row => 0, -sticky => 'nsew'); $mw->g_grid_columnconfigure(0, -weight => 1); $mw->g_grid_rowconfigure(0, -weight => 1); return $frame; } sub populate_framework { my ($frame) = @_; my ($string, $number); my $textvars = [ \($string, $number) ]; my $string_label = $frame->new_ttk__label(-text => 'String:'); $string_label->g_grid(-row => 0, -column => 0, -sticky => 'w'); my $string_entry = $frame->new_ttk__entry(-textvariable => \$strin +g); $string_entry->g_grid(-row => 0, -column => 1, -sticky => 'ew'); my $number_label = $frame->new_ttk__label(-text => 'Number:'); $number_label->g_grid(-row => 1, -column => 0, -sticky => 'w'); my $number_entry = $frame->new_ttk__entry(-textvariable => \$numbe +r); $number_entry->g_grid(-row => 1, -column => 1, -sticky => 'ew'); my $write_button = $frame->new_ttk__button(-text => 'Write', -command => [\&write_entries, $textvars] ); $write_button->g_grid(-row => 2, -column => 0, -sticky => 'ew'); my $clear_button = $frame->new_ttk__button(-text => 'Clear', -command => [\&clear_entries, $textvars] ); $clear_button->g_grid(-row => 2, -column => 1, -sticky => 'ew'); $_->g_grid_configure(-padx => 5, -pady => 5) for $frame->_kids; return; } sub write_entries { my ($entries) = @_; print join ',', map { $$_ } @$entries; return; } sub clear_entries { my ($entries) = @_; $$_ = '' for @$entries; return; }

        There shouldn't be anything in that code that you can't reference from the Tkx or Tkx::Tutorial documentation. I haven't attempted to show "Subclassing Tkx::widget": if you're currently having difficulties grasping strict, that may be a bit beyond your skills at the present; I would, however, encourage you to work towards it. I have used "Widget handles" throughout, which was something I discussed in an earlier response.

        "... however, I do have the "Introducing Perl/TK" book coming soon via mail."

        I own two Perl/Tk books: "Learning Perl/Tk" and "Mastering Perl/Tk" (both are now rather old — published in 1999 and 2002, respectively). I'm unfamiliar with "Introducing Perl/TK"; a link would have been useful.

        "Yet, I am totally lost as to use Tk or Tkx - the syntax does appear to be different. What method do you recommend?"

        I like Perl/Tk for a number of reasons, not least of which is the fact that I've been using it for about two decades and am very familiar with it. I've started to use Tkx recently mainly for cosmetic reasons: it just displays better on certain platforms.

        Yes, the syntax is different. I'm currently using Tkx for a private project and, by following the suggestions in "Subclassing Tkx::widget", I now have almost identical syntax. Even if it wasn't private, the main module for performing that subclassing, currently stands at 2,305 lines, so not really something I would post here; I am, however, happy to help with specific issues.

        See also: "Tcl::pTk - Interface to Tcl/Tk with Perl/Tk compatible syntax".

        — Ken

Re: Tkx and clear a textbox content
by zentara (Cardinal) on Aug 21, 2017 at 16:32 UTC
    Dosn't $textbox->delete(0, "end") work? What error do you get?

    I'm not really a human, but I play one on earth. ..... an animated JAPH

      G'day zentara,

      "Doesn't $textbox->delete(0, "end") work?"

      Whilst that is valid syntax, the OP hasn't written his code to take advantage of it. Instead of a Perl widget handle like $textbox, a Tcl pathname, like '.c.textbox', has been used. As per "Calling Tcl and Tk Commands", the required syntax would need to be the rather clunky:

      Tkx::i::call('.c.textbox', 'delete', 0 => 'end');

      Given the way the OP's code has been written, I think huck's solution of assigning empty strings is a better option. Unless I wanted to target just a portion of the displayed text, I'd probably choose variable modification over accessing an index-based range.

      Having said that, the OP's code has many problems, not least of which is the monolithic approach, with global variables just springing into existence without any regard for their scope. I wouldn't have written it like that to start with; in fact, the method described in the Tkx::Tutorial's section "Subclassing Tkx::widget" is a small amount of up-front work but results in much shorter, and easier to read, GUI code. Instead of code like:

      Tkx::ttk__entry(".frame.textbox", ...); Tkx::grid(".frame.textbox", ...); ... Tkx::i::call('.frame.textbox', 'function', ...);

      You can write something closer to:

      my $textbox = $frame->entry(...)->grid->(...); ... $textbox->function(...);

      Even with something as simple as the OP's GUI (5 entry, 5 label and 2 button widgets), the reduction in the amount of GUI code that needs to be written, and the improved readability, is clear.

      — Ken

        Thank you for your suggestions, and clear example. Also for taking the time to detail the different methods. I will be honest, I am not sure what is the correct way to program with the TCL/TK format as you point out. I am only using the Example from the TKDoc link

        http://www.tkdocs.com/tutorial/firstexample.html

        however, I do have the "Introducing Perl/TK" book coming soon via mail. Yet, I am totally lost as to use Tk or Tkx - the syntax does appear to be different. What method do you recommend?