Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Is there a simple way to bind a textvariable (for a Label say) to an array in such a way as to keep track of changes in the array's size? e.g. I want to label a ListBox with the number of entries in it. it seems that neither -textvariable => \@array nor -textvariable => \$#array do the trick. I'm beginning to think that the most straightfoward solution is to explicitly keep track of the array size in a separate scalar variable and use that as my -textvariable, of course that might lead me to create a silly object that contains an array and a scalar just to keep track of the array size. Apologies if this question is rudimentary.

Replies are listed 'Best First'.
Re: binding Tk textvariables
by davidj (Priest) on Jun 18, 2004 at 06:49 UTC
    You can use the size() method of the Listbox object to retrieve the number of elements in the Listbox. You can use this value for the -text option of the Label object or you can store it in a variable.

    Assuming you don't have any need to store the number of items in the Listbox in a variable for other needs, the following code sample will dynamically update the Label widget as items are added and removed from the Listbox.

    #!/usr/bin/perl use strict; use Tk; my $mw = MainWindow->new(qw/-width 300 -height 200/); my $lb = $mw->Listbox(-selectmode => "multiple")->pack(); my $label = $mw->Label(-text => "Empty")->pack(); my $add = $mw->Button(-text => "add item", -command => \&add )->pack(); my $delete = $mw->Button(-text => "delete item", -command => \&delete, )->pack(); MainLoop; sub add { $lb->insert('end', "item"); $label->configure(-text => "num elms = " . $lb->size()); } sub delete { my @elms = $lb->curselection; foreach (@elms) { $lb->delete($_); } $label->configure(-text => "num elms = " . $lb->size()); } exit;
    hope this helps,
    davidj
      Thanks for your suggestion. This clearly works, but it's the kind of thing I was hoping to avoid as I already have several subs that modify the number of elements in the listbox, and I was hoping to avoid having to chase down every place that happened. I should have made this more clear in the question. This does suggest a solution where any any subroutine that modifies the size of the listbox is required to use something like your add or delete to do so - but that would have required some forethought ;)
Re: binding Tk textvariables
by eserte (Deacon) on Jun 18, 2004 at 08:35 UTC
    Another possibility is to use a tied array which reflects a size variable if STORE, STORESIZE, CLEAR etc. is called. This is still a silly object, but at least you can use it as a normal array.
      This sounds like what I had in mind. Thanks. Now I just need to go find some documentation about how to do that... any pointers?
Re: binding Tk textvariables
by Anonymous Monk on Jun 18, 2004 at 15:00 UTC
    The solution I finally decided to go with doesn't really solve the problem as I originally posed it, but has all the functionality I required. Instead of using a label, I attach a balloon widget to the listbox with a -postcommand option which updates the balloon text to reflect the number of elements in the listbox (and the number selected for good measure). Thanks for your help!