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.
|