Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

perltk: error getting values from dynamically generated combo boxes

by ruhroh (Initiate)
on May 07, 2012 at 19:24 UTC ( #969316=perlquestion: print w/ replies, xml ) Need Help??
ruhroh has asked for the wisdom of the Perl Monks concerning the following question:

Hi perl monks, I am having an issue with retrieving values from a dynamically generated group of combo boxes. I am using an array to hold all of these combo boxes. I can only seem to access the most recent combo box and I get an error whenever I try to access the contents of an older combo box (so if I have two combo boxes, I get an error when I try to access the first one).

Here is the error that I get: Tk::Error: bad listbox index "": must be active, anchor, end, @x,y, or a number at /usr/intel/pkgs/perl/5.8.5/lib/site_perl/5.8.5/x86_64-linux/Tk.pm line 247. Tk callback for .browseentry.toplevel.frame.listbox Tk callback for .button1 Tk::__ANON__ at /usr/intel/pkgs/perl/5.8.5/lib/site_perl/5.8.5/x86_64-linux/Tk.pm line 247 Tk::Button::butUp at /usr/intel/pkgs/perl/5.8.5/lib/site_perl/5.8.5/x86_64-linux/Tk/Button.pm line 111 <ButtonRelease-1> (command bound to event)

Here is my code:

use strict; use warnings; use Tk; my $fieldcounter = 0; my $textboxrow = 1; my $fieldbuttonrow = 2; my @be; my @listb; my $mw = tkinit; $mw -> geometry("400x200"); $be[$fieldcounter] = $mw->BrowseEntry(-label=>"Field") ; $listb[$fieldcounter] = $be[$fieldcounter]->Subwidget('slistbox')->Sub +widget('scrolled'); my @content; tie @content,'Tk::Listbox', $listb[$fieldcounter]; @content = qw/dog cat mouse/; my $button = $mw->Button(-text => 'Add Field',-command => \&addtextbox +,); my $button2 = $mw->Button(-text => 'Print texts',-command => \&printte +xts,); $be[$fieldcounter] -> grid(-row=>$textboxrow,-column=>2); $button ->grid(-row=>$fieldbuttonrow,-column=>2,-columnspan=>2); $button2 ->grid(-row=>$fieldbuttonrow+1,-column=>2,-columnspan=>2); MainLoop(); sub addtextbox{ $fieldcounter++; $fieldbuttonrow++; $textboxrow++; $be[$fieldcounter] = $mw->BrowseEntry(-label=>"Field"); $listb[$fieldcounter] = $be[$fieldcounter]->Subwidget('slistbox')->Sub +widget('scrolled'); tie @content,'Tk::Listbox', $listb[$fieldcounter]; @content = qw/dog cat mouse/; $be[$fieldcounter] -> grid(-row=>$textboxrow,-column=>2); $button->grid(-row=>$fieldbuttonrow,-column=>2,-columnspan=>2); $button2->grid(-row=>$fieldbuttonrow+1,-column=>2,-columnspan=>1); } sub printtexts{ my $field_id; my $field; my $fields; my @fieldslist; for my $listb_index(0 .. $fieldcounter){ print "listb_index is $listb_index\n"; $field_id = $listb[$listb_index] -> curselection(); $field = $listb[$listb_index] -> get($field_id); push @fieldslist, $field; } $fields = join (':', @fieldslist); print "fields is: $fields\n"; }

Comment on perltk: error getting values from dynamically generated combo boxes
Download Code
Re: perltk: error getting values from dynamically generated combo boxes
by SuicideJunkie (Priest) on May 07, 2012 at 20:05 UTC
    Tk::Error: bad listbox index "": must be active, anchor, end, @x,y, or a number at /usr/intel/pkgs/perl/5.8.5/lib/site_perl/5.8.5/x86_64-linux/Tk.pm line 247

    So. You're giving a listbox index that is either an empty string or perhaps undef. The solution is to not do that :)

    Try printing out the values you're using, and then see where the bad value is coming from.

    You could also make a temporary tweak to Tk.pm, and have it confess instead.

      The problem is that:

      $field_id = $listb$listb_index -> curselection();

      only returns a value if it is retrieving a value from the last listbox created. Otherwise, it will return a value "". I have been looking at the documentation for listbox from: http://search.cpan.org/~srezic/Tk-804.030/pod/Listbox.pod . But I don't know why my script can't retrieve the values from the first created listbox.

      UPDATE: I did a check to see if the previous listboxes existed by just doing a get(0). They all print out dog as expected.

      So the problem is why doesn't curselection not work on the old listboxes and only the most recently "added" listbox?

        I tried to look back where your $listb is coming from. (needs a better name BTW - I've no idea what it is for) and it got confusing pretty quick.

        I suggest regenerating your indentation with perltidy, and taking a closer look at @content and the repeated ties. I'm not familiar with tie, but I'd guess that you're making a giant knot out of all your gui elements there.

Re: perltk: error getting values from dynamically generated combo boxes
by thundergnat (Deacon) on May 08, 2012 at 14:36 UTC

    That is happening because of the way the BrowseEntry widget handles mouse clicks.

    Mouse button 1 clicks outside of a BrowseEntry selection choice list clears the current selection. So only the last BrowseEntry you adjust will (possibly) still have a curselection list.

    I'm not sure exactly what you are trying to accomplish, but it seems like you are doing an awful lot of unnecessary work. Would something like this do what you want?

    use strict; use warnings; use Tk; my $textboxrow = 1; my $fieldbuttonrow = 2; my @be; my $mw = tkinit; $mw -> geometry("400x200"); my $button = $mw->Button(-text => 'Add Field', -command => \&addtext +box); my $button2 = $mw->Button(-text => 'Print texts',-command => \&printte +xts); addtextbox(); MainLoop(); sub addtextbox{ my $be = $mw->BrowseEntry(-label=>"Field"); $be->insert('end', $_) for qw/dog cat mouse/; push @be, $be; $be ->grid(-row=>$textboxrow++, -column=>2); $button ->grid(-row=>$fieldbuttonrow++,-column=>2,-columnspan=>2); $button2->grid(-row=>$fieldbuttonrow ,-column=>2,-columnspan=>1); } sub printtexts{ print join ':', map { $_->Subwidget('entry')->get } @be; }

      This seems to be what I needed. I wanted something that allows the user to input as many fields as he/she likes and a way to collect all of the fields the user inputted.

      Sorry I just started learning Perltk (a lot from your message boards tbh :D ) and this code is what I came up with. I really appreciate your help! Thanks!

        No apology necessary. We were all beginners once. Besides, you posted almost a perfect textbook example of the right way to ask a question. Made it easy to help you.

        Cheers

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://969316]
Approved by Corion
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2014-07-25 10:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (170 votes), past polls