in reply to Re: Sorted lists in Tk
in thread Sorted lists in Tk

Thanks for the code examples. As you suggested, I searched groups.google.com. I found there mention of a very powerful list widget, with built in sorting capabilities. Tk::MListbox. It's pretty impressive. Allows column sorting, hiding columns, etc. It's available as an activestate package. Life is good!

Replies are listed 'Best First'.
Re^3: Sorted lists in Tk
by zentara (Cardinal) on May 04, 2005 at 18:08 UTC
    There was a recent post on comp.lang.perl.tk about MListbox leaking memory, when you make alot of entry changes. I recommended in a response to use HList, because it's methods allow reuse of entries. I actually thought you were the same person who posted there, because he said the drawback to HList was no built-in sorting. Anyways...watch your memory with MListbox, if you are doing alot of entry changes.

    I'm not really a human, but I play one on earth. flash japh
      There was a recent post on comp.lang.perl.tk about MListbox leaking memory

      I see that. I tried rewriting the list using Tk::MListbox in my app. Whenever the sort functionality is used, it leaks about 20KB of memory. Just so I understand, with Tk::Hlist, you can't bind a sort function to the column, right? I don't really want to clutter things up with buttons, unless I have to. Is there any way to work around this memory problem? Your post had mentioned -reconfigure...
        20K per sort isn't too bad, if your app is not going to run for hours and hours. Even loading a image somewhere will cause a 20k increase.

        with Tk::Hlist, you can't bind a sort function to the column, right?

        You can, it just isn't obvious from the docs. What you need to do is tell Hlist to use a Button for the header, as in the code below. To bind on the "whole column", there is the x->ev and y->ev methods, but I don't have snippet offhand for that(plus you will be messing with the hlist bindings, unless you use a "right-click" to sort).

        #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::HList; # googled example by Rob Seegel my $mw = new MainWindow; my $hl = $mw->Scrolled( 'HList', -scrollbars => 'os', -background => 'white', -columns => 4, -header => 1, -width => 40, -height => 5 )->pack; my $bgcolor = "bisque"; foreach my $column ( 0 .. 3 ) { ## Create the Clickable Header my $b = $hl->Button( -background => $bgcolor, -anchor => 'center', -text => "Header$column", -command => sub { print "You pressed Header $column\n"; } ); $hl->headerCreate( $column, -itemtype => 'window', -borderwidth => -2, -headerbackground => $bgcolor, -widget => $b ); } MainLoop;

        The first HList example I showed you used itemConfigure. Now MListbox and Listbox don't have itemConfigure, but they are simpler to use. In simple situations, like the first HList sort example, you can get away with $hl->delete('all'), then recreate them all, with no memory gain. However, it is a very simple HList, with just text items. If you get into fancier HList's, say having thumbnail images in the list, Perl's internal reference counting mechanism, will cause HList to leak too, if you do the simpler "delete-rebuild method". In those cases, you have to use itemConfigure to reconfigure each entry with new data. So I generally just stick to itemConfigure all the time.

        There are ways to avoid memory gains with Listbox, for instance, the first snippet below will leak, but not the second.

        #!/usr/bin/perl -w use strict; use Tk; #this leaks my $mw = Tk::MainWindow->new( -title => 'Listbox Leak' ); my $lb = $mw->Listbox()->pack(); my $b = $mw->Button( -text => 'Leak', -command => \&leak )->pack(); MainLoop; sub leak { $lb->delete( 0, 'end' ); $lb->insert( 'end', 1 .. 10000 ); }
        ##################################### #!/usr/bin/perl use warnings; use strict; use Tk; #no leaks, but watch out for @array being empty...crash #make sure @array has at least a ''; my $mw = Tk::MainWindow->new(-title => 'Listbox Leak'); my @array = (1..10000); my $lb = $mw->Listbox( -listvariable=> \@array, )->pack(); my $b = $mw->Button(-text => 'Leak', -command => \&leak )->pack(); MainLoop; sub leak { @array = map{"$_.a"}(1..10000); $lb->update; }

        Now I havn't messed around much with MList, but any list which allows you do put another object (like a Button) into the list, will leak if you delete entries with a still defined Button in it.


        I'm not really a human, but I play one on earth. flash japh