G'day Rolf,

I completely understand where you are coming from. I write a lot of Tk code. I've posted a fair amount on this site; however, I tend to completely ignore presentation in those cases, focussing mainly on pure functionality (questions are typically along the lines of "How do I make X do ...", as opposed to "How do I make X look like ..."). On the other hand, for my personal code, presentation is important; over the years, I've come up with a variety of techniques to circumvent verbosity and repetition.

For any GUI application, you want a consistent look and feel. This is something that should be specified once (DRY principle). Take a look at the option database, Tk::option, to achieve this. You can set up colours, fonts, etc. globally, e.g. *background; override that for specific types of widgets, e.g. *Button*background; and even override that for individual widgets using the Name option (I've never needed that but it is documented).

With that alone, code that previously looked like:

$parent->Widget( -background => ..., -foreground => ..., ... other option/value pairs ... -padX => ..., -padY => ..., )

would now be simply:

$parent->Widget()

If you do decide to use the option database, I'd strongly recommend that you do use the optional 'priority' and set it 'startupFile'. This will allow: hard-coded widget defaults to be used where you haven't defined something different; user preferences (e.g. from .Xdefaults) to override your choices; and, the ability to have fine-grained control override everything (e.g. a Label with an error message might want emboldened, red text).

Because option/value pairs are just a list, you can reduce

-optionA => valueA, -optionb => valueB, -optionC => valueC

to

qw{-optionA valueA -optionb valueB -optionC valueC}

Obviously, that doesn't work where values are variables, coderefs, strings with spaces, and so on; however, overall, I find that to be generally usefully. And, of course, you can combine the two styles:

qw{-option1 value 1 ... -optionN valueN -command}, sub { ... }

Automatically adding ->pack() is probably a bad idea; I've never done it but it should be possible (perhaps with subclassing to give, for example, a PackedButton widget). In a number of cases you'll want to separate the widget creation and geometry management operations with intervening code; automatically adding ->pack(), ->grid(), etc. is problematic in these instances.

The options passed to geometry management methods are likely to be mostly identical to achieve a consistent look and feel. Again, apply the DRY principle. There a number of ways to do this; I typically use something like this:

... sub _std_btn_pack_opts () { return (-side => left, -padx => 5, -pady 2); } ... $parent->Button(...)->pack(_std_btn_pack_opts); ...

You can, of course, add options and override the standard ones, e.g.

$parent->Button(...)->pack(_std_btn_pack_opts, -anchor => 'n', -side = +> 'right');

[Note: I have researched adding geometry management options to the option database but haven't been able to find a way to do that. If it is at all possible, I'd be very happy to hear about it.]

It's unclear what you were trying to demonstrate with five 'my $t1' instances in the same lexical scope. Unless you need to subsequently reference a widget, there is no point in assigning it to a variable. Here's a rough example showing where assignments would be needed.

my $frame = $parent->Frame()->pack(); # NEEDED $frame->Label(-text => 'Status Control')->pack(); # NOT NEEDED my $status1 = $frame->Label(-text => $statmsg1)->pack(); # NEEDED $frame->Label(-textvariable => \$statmsg2)->pack(); # NOT NEEDED $frame->Button( -text => 'Update Status 1', -command => sub { $status1->configure(-text => $new_statmsg1); }, )->pack(); # NOT NEEDED

Update: I added '->pack()' to the last statement in the last example ($frame->Button(...)). Not really needed for the example; just keeps things consistent.

— Ken


In reply to Re: Verbose Tk Code by kcott
in thread Verbose Tk Code by LanX

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.