First, the minor bugs and questionable code; here is a diagram of your control tree:
# MainWindow $MW # Frame Frame1 # Labelframe SourceFrame # Label SourceTypeLabel # Optionmenu SourceTypeMenu # Frame sourceoneFrame # Mutually exclusive # Frame sourcetwoFrame # Mutually exclusive # Label StringLabel
To fix the abort, I reached the same conclusion that you did; wrap sub{ } around the value side of
Why did the original version fail? Because -command expects a coderef, but your code is an *immediate* call to-command => $typeframes{'source'}->{ $config{'sourcetype'} }->( \%tkobjects ),
By wrapping it all in sub{ }, you create a closure where (for example) $config{'sourcetype'} will supply its hash value as of the time of invocation, instead of at the time of definition. See perlfaq7 and perlref for more on closures.
When I refactored the code to reflect the closure, I came up with this version; it replaces the code just before MainLoop:
# $option_command will be an anon sub, # with sole access to %typeframes. my $option_command; { my %typeframes = ( 'source' => { 'one' => \&makeSourceoneFrame, 'two' => \&makeSourcetwoFrame, } ); $option_command = sub { my $option = shift; $typeframes{'source'}->{ $option }->( \%tkobjects ); } } $tkobjects{'SourceTypeMenu'} = $tkobjects{SourceFrame}->Optionmenu( # -variable => \$config{'sourcetype'}, # No longer needed! -command => $option_command, -options => \@TYPES )->grid( -row => 1, -column => 1, ); # By naming the anon sub (via variable), we avoid # repeating code here. $option_command->('one'); # Actually, we don't have to manually invoke $option_command; # it got called with the first (default) option when # the OptionMenu was created! MainLoop;
In reply to Re: Tk destroy method dies with "Aborted"
by Util
in thread Tk destroy method dies with "Aborted"
by g0n
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |