I would say that you are trying to use the wrong widgets to do what you want.
First, you will have problems getting the columns to line up between a label and a ROText widget. Their is no uniform connection between the 2, especially if you allow font changes
Second, sorting on a column will be tricky, but can be done. You will have to read all your ROText, split on tabs, sort, then rewrite.....all hoping that the columns will still line up with the headers.
You might be able to work out some sort of Table with TableMatrix, because it sounds like you are looking for a way for your data to display like an html table would. That is an auto-adjust of column width to the largest entry.
A variant of this question was asked a few weeks ago, about sorting lists by clicking on the headers. Sorry that I can't find the node, but had to do with MListbox leaking some memory.
Anyways, you should look at one of the listbox modules. MListbox is designed for column sorting. I recommended the HList, which is harder to use, but can be made to run without leaking memory on sorting. MListbox probably can too, but I don't have a good MListbox example handy. So here is an HList example:
#!/usr/bin/perl
use strict;
use Tk;
use Tk::HList;
my $mw = MainWindow->new();
#create some sample data
my %data;
foreach (0..100) {
$data{$_}{'name'} = 'name'.$_;
$data{$_}{'id'} = rand(time);
$data{$_}{'priority'} = int rand 50;
}
#get random list of keys
my @keys = keys %data;
#################
my $h = $mw->Scrolled( 'HList',
-header => 1,
-columns => 3,
-width => 40,
-height => 40,
-takefocus => 1,
-background => 'steelblue',
-foreground =>'snow',
-selectmode => 'single',
-selectforeground => 'pink',
-selectbackground => 'black',
# -browsecmd => \&browseThis,
)->pack(-side => "left", -anchor => "n");
$h->header('create', 0, -text => ' Name ',
-borderwidth => 3,
-headerbackground => 'steelblue',
-relief => 'raised');
$h->header('create', 1, -text => ' ID ',
-borderwidth => 3,
-headerbackground => 'lightsteelblue',
-relief => 'raised');
$h->header('create', 2, -text => ' Priority ',
-borderwidth => 3,
-headerbackground => 'lightgreen',
-relief => 'raised');
foreach (@keys) {
my $e = $h->addchild(""); #will add at end
$h->itemCreate ($e, 0,
-itemtype => 'text',
-text => $data{$_}{'name'},
);
$h->itemCreate($e, 1,
-itemtype => 'text',
-text => $data{$_}{'id'},
);
$h->itemCreate($e, 2,
-itemtype => 'text',
-text => $data{$_}{'priority'},
);
}
my $button = $mw->Button(-text => 'exit',
-command => sub{exit})->pack;
my $sortid = $mw->Button(-text => 'Sort by Id',
-command => [\&sort_me,1] )->pack;
my $sortpriority = $mw->Button(-text => 'Sort by Priority',
-command => [\&sort_me,2] )->pack;
MainLoop;
#########################################################
sub sort_me{
my $col = shift;
my @entries = $h->info('children');
my @to_be_sorted =();
foreach my $entry(@entries){
push @to_be_sorted,
[ $h->itemCget($entry,0,'text'),
$h->itemCget($entry,1,'text'),
$h->itemCget($entry,2,'text'),
];
}
my @sorted = sort{ $a->[$col] cmp $b->[$col] || #primary sort ascii
+
$a->[1] <=> $b->[1] #secondary sort num
+eric
} @to_be_sorted;
my $entry = 0;
foreach my $aref (@sorted){
# print $aref->[0],' ',$aref->[1],' ',$aref->[1],"\n";
$h->itemConfigure( $entry, 0, 'text' => $aref->[0] );
$h->itemConfigure( $entry, 1, 'text' => $aref->[1] );
$h->itemConfigure( $entry, 2, 'text' => $aref->[2] );
$entry++;
}
$mw->update;
}
__END__
I forgot to include the code for doing a "Clickable Header"
in an HList
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use Tk::HList;
my $mw = new MainWindow;
my $'HList',->Scrolled(
-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;