I'm writing a Tk-perl script, where there are a different number of textfields to complete, and their labels are different, according to the choice of "type". I thought a neat way to do this would be a callback attached to the drop down menu that creates a subframe. Then, if you switch to the other "type", the subroutine checks to see if the other type of frame exists, destroys it if it does, and creates the selected subframe.
Conceptually, I think the approach is OK, but the script dies with
Aborted
when destroy is called.
The script itself is fairly huge, so I've worked up a minimal test case. Could someone tell me a) what's going wrong, or b) whether it works on their set up, or c) whether there's a better way of doing it?
Code below:
#!/usr/bin/perl use strict; use warnings; use Tk; main(); ###################################################################### +################## # main ###################################################################### +################## sub main { my %tkobjects; # mainwindow my $MW; # # User-defined variables (if any) # my @TYPES = qw(one two); my %config = ( 'sourcetype' => "one" ); my %typeframes = ( 'source' => { 'one' => \&makeSourceoneFrame, 'two' => \&makeSourcetwoFrame } ); ###################### # # Create the MainWindow # ###################### $MW = MainWindow->new; # Widget Frame1 isa Frame $tkobjects{'Frame1'} = $MW->Frame()->grid( -row => 2, -column => 0, -sticky => 'e', ); ###################################################################### +### # source frame ###################################################################### +### # Widget SourceFrame isa Labelframe $tkobjects{'SourceFrame'} = $tkobjects{Frame1}->Labelframe( -text => 'Source' )->grid( -row => 1, -column => 0, -sticky => 'ns', ); # Widget SourceTypeLabel isa Label $tkobjects{'SourceTypeLabel'} = $tkobjects{SourceFrame}->Label( -text => 'Type', )->grid( -row => 1, -column => 0, ); # Widget SourceTypeMenu isa Optionmenu $tkobjects{'SourceTypeMenu'} = $tkobjects{SourceFrame}->Optionmenu +( -variable => \$config{'sourcetype'}, -command => $typeframes{'source'}->{ $config{'sourcetype'} }->( \%tkobje +cts ), -options => \@TYPES )->grid( -row => 1, -column => 1, ); $typeframes{'source'}->{ $config{'sourcetype'} }->( \%tkobjects ); ############### # # MainLoop # ############### MainLoop; } ###################################################################### +### # make source one frame ###################################################################### +### sub makeSourceoneFrame { my $tkobjectsref = shift; my %tkobjects = %$tkobjectsref; # if switching to one, destroy the twoframe if ( $tkobjects{'sourcetwoFrame'} ) { $tkobjects{'sourcetwoFrame'}->destroy; } $tkobjects{'sourceoneFrame'} = $tkobjects{'SourceFrame'}->Frame()- +>grid( -row => 2, -column => 0 ); # Widget SourceSelectString isa Label $tkobjects{'StringLabel'} = $tkobjects{SourceFrame}->Label( -text => "string two", )->grid( -row => 3, -column => 0, ); } ###################################################################### +### # make source two frame ###################################################################### +### sub makeSourcetwoFrame { my $tkobjectsref = shift; my %tkobjects = %$tkobjectsref; # if switching to two, destroy the one frame if ( $tkobjects{'sourceoneFrame'} ) { $tkobjects{'sourceoneFrame'}->destroy; } $tkobjects{'sourcetwoFrame'} = $tkobjects{'SourceFrame'}->Frame()- +>grid( -row => 2, -column => 0 ); $tkobjects{'StringLabel'} = $tkobjects{SourceFrame}->Label( -text => "string two", )->grid( -row => 3, -column => 0, ); }
Tk version is 804.027, perl version is 5.8.7, OS is Linux.
Update: Fed the code through perltidy.
Update: It appears to be the callback syntax that's causing the error - if the if blocks and their contents calling destroy are commented out, the same thing happens.
Update: Found a solution. The syntax -command =>sub {$typeframes{'source'}->{ $config{'sourcetype'} }->(\%tkobjects) }, works. I'd still be grateful for comments on that syntax though, because it looks quite nasty.
--------------------------------------------------------------
$perlquestion=~s/Can I/How do I/g;
In reply to Tk destroy method dies with "Aborted" by g0n
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |