Revered Monks,
It is with humility and penitence that I bring to you my first question. Please forgive my ungraceful coding style and lengthy post, as I am new to this monastery, and am but a lowly electrical engineering student.

I am an engineering intern for the summer, and have been made by my superiors to learn to code in Perl. Among other things, I have to program a GUI that allows the engineers to create a list of solutions to a problem from an established list. They also have to be able to edit/remove any one of these solutions from the same interface.

The issue I'm having is as follows: I (plan to) load the available solutions from a text file into $AvailListbox, from which they can be moved to and from $SelectedListbox using two buttons. If a solution needs to be removed or modified, I have a button that opens a Toplevel into which (for convenience) I pack the already existing $AvailListbox.

When I withdraw the Toplevel, however, $AvailListbox is still present in $MW, but can no longer be accessed as an element thereof. In other words, any subroutine I try to call using $AvailListbox->curselection() does not work on the selection in $MW, but rather in the Toplevel, even after it has been withdrawn. I'm wondering how I would go about restoring the "control" over $AvailListbox to $MW. And hopefully that makes sense.

Here are some relevant sections, with most of the formatting calls in pack() or widget creations removed, for readability. If you paste all the snippets of code together, it should reproduce the same scenario as I mention above.

Here I create $AvailListbox, which holds the available solutions.
#!/usr/local/bin/perl use warnings; use strict; use Tk; # Predeclaring the subroutines and variables sub initialize_step_selection(); sub select_soln_step(); sub deselect_soln_step(); sub modify_remove_step_dialog(); # Building the GUI skeleton, i.e. predeclaring some widgets my $MW = MainWindow->new; my $StepFrame; my $AvailListbox; my $SelectListbox; # Run the subroutines initialize_step_selection(); MainLoop(); # Creates the solutions frame, and its contents sub initialize_step_selection() { # Frame for selecting solutions $StepFrame = $MW->Frame(); $StepFrame->pack(-fill => 'both'); # Scrollbars for available solutions my $AvailScroll = $StepFrame->Scrollbar(-orient => 'vertical +'); # Listbox of available solutions $AvailListbox = $StepFrame->Listbox(-yscrollcommand => ['set +' => $AvailScroll]); $AvailListbox->pack(-fill => 'y', -side => 'left'); $AvailScroll->configure(-command => ['yview' => $AvailLis +tbox]); $AvailScroll->pack(-fill => 'y',-side => 'left'); $AvailListbox->insert('end', "Just", "for", "testing", "purposes") +; # Scrollbar for selected solutions my $SelectScroll = $StepFrame->Scrollbar(-orient => 'vertica +l'); # Listbox of selected solutions $SelectListbox = $StepFrame->Listbox(-yscrollcommand => ['se +t' => $SelectScroll]); $SelectListbox->pack(-fill => 'y', -side => 'left'); $SelectScroll->configure(-command => ['yview' => $SelectL +istbox]); $SelectScroll->pack(-fill => 'y',-side => 'left'); # Select/Deselect solutions buttons my $SelectStep = $StepFrame->Button(-text => ">",-command + => sub{select_soln_step();}); $SelectStep->pack(); my $DeselectStep = $StepFrame->Button(-text => "<",-command + => sub{deselect_soln_step();}); $DeselectStep->pack(); my $ModRmvStep = $StepFrame->Button( -text => "Modify/Remove a Step", -command => sub{modify_remove_step_dialog();} ); $ModRmvStep->pack( -padx => 2, -pady => 3); } # Closing initialize_step_selection()
And then I repack $AvailListbox in the Toplevel here:
sub modify_remove_step_dialog() { my $ModRmvStep = $MW->Toplevel(); $ModRmvStep->title("Modifier une étape"); my $MRSFrame1 = $ModRmvStep->Frame(-label => "Sélectionnez u +ne étape à modifier"); $MRSFrame1->pack(-fill => 'both'); # Listbox of available solutions my $StepModRmvScroll = $MRSFrame1->Scrollbar(-orient => 'ver +tical'); $AvailListbox = $MRSFrame1->Listbox(-yscrollcommand => ['set +' => $StepModRmvScroll]); $AvailListbox->pack(-fill => 'both', -side => 'left +'); $AvailListbox->insert('end', "Just", "for", "testing", "purposes") +; # Configuring available listbox scrollbars $StepModRmvScroll->configure(-command => ['yview' => $Ava +ilListbox]); $StepModRmvScroll->pack(-fill => 'y', -side => 'left') +; my $MRSFrame2 = $ModRmvStep->Frame(); $MRSFrame2->pack(-fill => 'both'); my $MRSMod = $MRSFrame2->Button(-text => 'Rien'); $MRSMod->pack(); my $MRSCancel = $MRSFrame2->Button(-text => 'Rien'); $MRSCancel->pack(); my $MRSRmv = $MRSFrame2->Button(-text => 'Cancel', -command + => sub{$ModRmvStep->withdraw;}); $MRSRmv->pack(); }
Now, when I call sub select_soln_step() by pushing the top button in the $MW, it moves the selected solution from the left box to the right one. The bottom button does the opposite:
# This subroutine will move the selected solution from the AvailListbo +x # to the SelectListbox sub select_soln_step() { # Get the contents of the current selection my $selIndex = $AvailListbox->curselection(); # If no item is selected, we do nothing. unless($selIndex eq "") { my $selection = $AvailListbox->get($selIndex); # Remove the selected value from the AvailListbox, and add it +to the SelectListbox $SelectListbox->insert('end', $selection); $AvailListbox->delete($selIndex); } } # This subroutine will move the selected solution from the SelectListb +ox # to the AvailListbox sub deselect_soln_step() { # Get the contents of the current selection my $selIndex = $SelectListbox->curselection(); # If no item is selected, we do nothing. unless($selIndex eq "") { my $selection = $SelectListbox->get($selIndex); # Remove the selected value from the AvailListbox, and add it +to the SelectListbox $AvailListbox->insert('end', $selection); $SelectListbox->delete($selIndex); } }
However, once the Toplevel has been opened, the button to move the solutions from the left box to the right one no longer works on the curselection(); in $MW, but on the curselection(); in the Toplevel... Is there any way to give control over $AvailListbox to $MW?

In reply to Tk - Giving control over a Widget to $MW from a Toplevel by ezzeloharr

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.