Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to make a sortable scrollable listbox like Explorer

101 views
Skip to first unread message

$Bill

unread,
May 9, 2013, 10:41:56 PM5/9/13
to
I'm no expert in Tk, but I can usually figure out how to do the basics.
Right now I have a Scrolled Listbox inside of a Labelframe that is
basically made up of a bunch of rows of data with the same type of info
in each column. Row 0 has the column title/header. Each row is basically
a sprintf into columns to form the same info for that item - it looks a
lot like the Windows Explorer window.

What I'd like to do is switch from 'pack' and outputting full rows on
each update to a 'grid' format where I can update each field in each row
independently. I also want to be able to re-sort the data based on column
by clicking the header for that column (I assume using a button here).

Example:
Col1 Col2 Col3 Col4 (change these to buttons)
Row0 Text Text ... (each of these would be similar to the info on a file in Explorer)
Row1 Text ...

The headers on each column (eg: 'Col1', ...) and each row's content are
currently a text insert for the entire row. I'd like to make the column
headers into buttons and when that button is pushed, it would re-sort
the rows based on the info in that column (just like Explorer's main window
with 'Name', 'Size', 'Date Modified', 'Type', etc and each row being a
file/directory). Clicking the 'Size' button would cause me to re-sort
the data by file size (up/down arrows on the column title button would be
nice too).

What I need is a schematic of what widgets to use and how to pack them
into a scrolled frame of some sort using grid instead of pack. So the
question is what do I use for the basic widget (has to be scrolled) and
how do I pack the buttons and text widgets into the array/grid ? Got
to believe this has been done before, so all I really need is a pointer/link.

A simple example (I've been searching for hours) of how to do this simple
application would be a boon to my mental health. Anything similar to a
Windows Explorer type of window using grid would be great. Just a list
of parent and slave widgets to use and how to grid them would be enough
to get me in the right direction (never used grid before and so far don't
quite understand it).

TIA, Bill

PS: Using straight Perl/Tk (not Tkx).

Marc Dashevsky

unread,
May 10, 2013, 1:36:51 AM5/10/13
to
I use a Scrolled('HList'). Email me at marc&marcdashevsky&com and I can
send you my little application.

In article <S7Zit.31$d5...@newsfe16.iad>, ne...@todbe.com says...

Marc Dashevsky

unread,
May 10, 2013, 2:04:43 AM5/10/13
to
Well, I stripped a lot of stuff out of the leaving just the Tk stuff.
I hope it makes some sense

use strict;
use warnings;
use Tk;
use Tk::Dialog;
use Tk::HList;
use Tk::ItemStyle;

my @AllFields = (
{db => 'NAME', text => 'Name', all => 1, button => undef},
{db => 'TOOL_CLASS', text => 'Class', all => 1, button => undef},
{db => 'TOOL_ID', text => 'ID', all => 0, button => undef},
{db => 'OBJECTTYPE', text => 'Type', all => 0, button => undef},
{db => 'IS_2X_TOOL', text => '2X', all => 1, button => undef},
{db => 'COMMAND_LINE', text => 'Command Line', all => 1, button => undef},
);

my $mw = tkinit(-title => $toolLabel);
$mw->fontCreate('normal', -family => 'Helvetica', -size => 9);
$mw->fontCreate('option', -family => 'Helvetica', -size => 9);
$mw->fontCreate('button', -family => 'Helvetica', -size => 11, -weight => 'normal');
$mw->fontCreate('error', -family => 'Helvetica', -size => 11, -weight => 'bold');
$mw->fontCreate('colhead', -family => 'Helvetica', -size => 10, -weight => 'bold');
$mw->fontCreate('bold', -family => 'Helvetica', -size => 9, -weight => 'bold');
$mw->fontCreate('italic', -family => 'Helvetica', -size => 9, -slant => 'italic');
$mw->optionAdd('*font' => 'normal');
DisplayWindow();
MainLoop;
exit(0);

#==========================================================================
sub DisplayWindow {
#==========================================================================
my($row, $col);
my $fl = $mw->Frame->pack(-anchor => 'w');
$fl->Label(-textvariable => \$RecordCount)->pack(-side => 'left');
$HL = $mw->Scrolled('HList',
-header => 1,
-columns => scalar(@AllFields),
-selectmode => 'extended',
-scrollbars => 'osoe',
-exportselection => 1,
)->pack(-expand => 1, -fill => 'both');
$mw->bind('all', '<MouseWheel>',
[sub{ $HL->yview('scroll', -($_[1] / 120) * 3, 'units') }, Ev('D')],
);
my $f = $mw->Frame()->pack(-fill => 'x');
my $f0 = $f->Frame(-bd => 2, -relief => 'groove')->pack(-side => 'left', -padx => 8, -pady => 6, -ipady => 6);
for (0 .. $#AllFields) {
my $b = $HL->Button(
-text => $AllFields[$_]->{text},
-command => [\&ListTools, 0, $_],
-font => 'colhead',
-relief => 'flat',
);
$HL->headerCreate($_, -itemtype => 'window', -window => $b);
push(@Headers, $b);
$AllFields[$_]->{button} = $b;
}
$Headers[0]->configure(-fg => $HeaderHilite);

my $fRight = $f->Frame->pack(-side => 'left', -fill => 'both', -pady => 8);
my $fbut = $fRight->Frame->pack(-fill => 'x', -pady => 8);
$QueryButton = $fbut->Button(
-text => 'Query',
-command => [\&ListTools, 1, 0],
-width => 10,
-font => 'button',
)->pack(-side => 'left', -padx => 20);
$ExitButton = $fbut->Button(
-text => 'Exit',
-command => [$mw, 'destroy'],
-width => 10,
-font => 'button',
)->pack(-side => 'right', -anchor => 'e', -padx => 20);
$fRight->Label(
-font => 'error',
-fg => '#C00000',
-anchor => 'w',
-textvariable => \$ErrorMessage,
)->pack(-fill => 'x', -pady => 8);
}

#==========================================================================
sub ListTools {
#==========================================================================
my(
$query,
$sortBy,
) = @_;
#==========================================================================
$ErrorMessage = '';
$mw->update;
@Records = ();
for each record
extract fields from database and put them in @f
push(@Records, \@f);
}
@Records = sort { lc($a->[$sortBy]) cmp lc($b->[$sortBy]) } @Records;
$_->configure(-fg => '#000000') for @Headers;
$Headers[$sortBy]->configure(-fg => $HeaderHilite);
$HL->delete('all');
OutputData($HL);
$mw->update;
}

#==========================================================================
sub OutputData {
#==========================================================================
my(
$hlistWidget,
) = @_;
#==========================================================================
for (0 .. $#AllFields) {
my $b = $AllFields[$_]->{button};
$b->configure(-text => ($Params{misc_all_objects} or $AllFields[$_]->{all}) ? $AllFields[$_]->{text} : '') if $b;
}
my $r = 0;
for my $rec (@Records) {
$hlistWidget->add($r);
for (0 .. $#AllFields) {
my $text = $rec->[$_] || '';
my $style = $Styles{left}->[$r & 1];
$hlistWidget->itemCreate($r, $_, -text => $text, -style => $style);
}
$r++;
}
}

__END__


In article <S7Zit.31$d5...@newsfe16.iad>, ne...@todbe.com says...
>

$Bill

unread,
May 10, 2013, 3:53:06 AM5/10/13
to
On 5/9/2013 23:04, Marc Dashevsky wrote:
>
> use Tk::Dialog;
> use Tk::HList;
> use Tk::ItemStyle;

Lots of errors that I fixed to get a clean run and get the basic drift of it.
Will continue looking at it in the morning and see what I can make of it.

Looks pretty much like what I was already doing as far as the content portion.
I like the way the header buttons work vs my plain text original version.

Looking at the pod, it says:

"The HList widget can be used to display any data that have a
hierarchical structure, for example, file system directory trees. The
list entries are indented and connected by branch lines according to
their places in the hierachy."

My data doesn't have a tree type structure per se, so not sure how this
would directly apply to my situation. I was thinking a grid would be more
appropriate, but I'll peruse a bit before I jump to any conclusions.

My app is extremely close to the Explorer app main file pane (or whatever
it's called) in detail mode without any directory depth. So it's just a
flat array of rows and columns - no working down a tree to worry about
(but might be a useful thing in the future if I add functionality).

Thanks a lot for your input - will ponder ...

Marc Dashevsky

unread,
May 10, 2013, 9:08:23 AM5/10/13
to
In article <uH1jt.8$0v...@newsfe11.iad>, ne...@todbe.com says...
>
> On 5/9/2013 23:04, Marc Dashevsky wrote:
> >
> > use Tk::Dialog;
> > use Tk::HList;
> > use Tk::ItemStyle;
>
> Lots of errors that I fixed to get a clean run and get the basic drift of it.
> Will continue looking at it in the morning and see what I can make of it.
>
> Looks pretty much like what I was already doing as far as the content portion.
> I like the way the header buttons work vs my plain text original version.
>
> Looking at the pod, it says:
>
> "The HList widget can be used to display any data that have a
> hierarchical structure, for example, file system directory trees. The
> list entries are indented and connected by branch lines according to
> their places in the hierachy."

This use is not indented. It's really just a rich Listbox.

> My data doesn't have a tree type structure per se, so not sure how this
> would directly apply to my situation. I was thinking a grid would be more
> appropriate, but I'll peruse a bit before I jump to any conclusions.
>
> My app is extremely close to the Explorer app main file pane (or whatever
> it's called) in detail mode without any directory depth. So it's just a
> flat array of rows and columns - no working down a tree to worry about
> (but might be a useful thing in the future if I add functionality).
>
> Thanks a lot for your input - will ponder ...

I wish I could have given you a whole working program, but even when
intact it would work only with a proprietary CMS.

$Bill

unread,
May 11, 2013, 1:10:46 AM5/11/13
to
On 5/10/2013 06:08, Marc Dashevsky wrote:
>
> I wish I could have given you a whole working program, but even when
> intact it would work only with a proprietary CMS.

You'd think there would already be a widget that does most of what I want
since it seems to be a useful tool. If I could figure out a little more
about how to build widgets and use grid, I could probably whip something up
myself eventually that would be a generic version of an Explorer type pane
(but not restricted to a file system). I just haven't studied it enough
to build my own module/widget.

TA, still working on dissecting your info - busy day, Bill


0 new messages