Esteemed monks,

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

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.