Perl/TkFAQ-10.8.如何配置用一个滚动条来控制多个组件

王朝perl·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

原文:

10.8. How do I configure a Scrollbar to scroll multiple widgets?

Note that the widget type that you wish to scroll can be important as a scroll "unit" on a Text or Listbox may be a character (several pixels - depending on font) whereas it would be an X "units" on a Canvas (could be pixel - but you may also specify other units).

A concrete answer for scrolling 3 Listboxes comes courtesy of Frederick L. Wagner <derf@ti.com>:

From a working example of multi-xscrolling:

sub multiscrollx { # multiscrollx my ($sb,$wigs,@args) = @ARG; my $w; foreach $w (@$wigs) { $w->xview(@args); } } # multiscrollx # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% $sh->configure( -command => [ \&multiscrollx, $sh, [$scratchrule,$ruleheader,$ruletable]]); $ruletable->configure( -xscrollcommand => [ 'set', $sh]); $ruleheader->configure( -xscrollcommand => [ 'set', $sh]); $scratchrule->configure(-xscrollcommand => [ 'set', $sh]);In this case,

$sh is a horizontal Scrollbar,

$ruletable and $scratchrule are Tables

$ruleheader is an Entry

However, this approach is good for any widget with X-scrolling capability, I think. So the Y counterpart should be:

sub multiscrolly { # multiscrolly my ($sb,$wigs,@args) = @ARG; my $w; foreach $w (@$wigs) { $w->yview(@args); } } # multiscrolly # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% $sv->configure( -command => [ \&multiscrolly, $sv, [$l1,$l2,$l3]]); $l1->configure( -yscrollcommand => [ 'set', $sv]); $l2->configure( -yscrollcommand => [ 'set', $sv]); $l3->configure( -yscrollcommand => [ 'set', $sv]);

Hope that helps.

Greg VanSickle mailto:vansickl@bnr.ca points out that this little script snippet does not provide for the binding of '<Button-2<' that he is accustomed to. He wrote a package called DSListbox to address this binding issue.

Conversely, Jong Park asked how to setup multiple Scrollbars to scroll the same widget. Nick Ing-Simmon's reply makes use of an anonymous sub and can be summed up in a little script that scrolls a Text widget (to see the scrolling in action type more than 20 lines of text into the widget):

#!/usr/local/bin/perl -w use Tk; my $mw = MainWindow->new(); my $s1 = $mw->Scrollbar(-orient => 'vertical'); my $s2 = $mw->Scrollbar(-orient => 'vertical'); $s1->pack(-side => 'left', -fill => 'y'); my $t = $mw->Text( -yscrollcommand => sub{$s1->set(@_), $s2->set(@_)}, -wrap => 'word', -width => 70, -height => 20, -font => $font, -setgrid => 1, )->pack(-side => 'left'); $s2->pack(-side => 'right', -fill => 'y'); $s1->configure(-command => [$t => 'yview']); $s2->configure(-command => [$t => 'yview']); MainLoop; __END__

译文:

10.8. 如何配置用一个滚动条来控制多个组件?

首先,值得注意的是,对于Text或Listbox等组件而言,滚动的“单位”可能是一个字符的(相当于十几个或几十个象素——这取决于字体的大小),而对于像Canvas这样的组件而言则就是一个象素(当然你也可以指定其它的单位)。因此,当你在考虑要用一个滚动条来同时控制多个组件的时候,可能需要考虑一下组件的类型。

尊敬的Frederick L. Wagner先生提供了一个同时滚动三个组件的具体例子:

(取自一个实际的多组件横行滚动的例子)

sub multiscrollx

{ # multiscrollx

my ($sb,$wigs,@args) = @_;

my $w;

foreach $w (@$wigs)

{

$w->xview(@args);

}

} # multiscrollx

# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

$sh->configure( -command => [ \&multiscrollx, $sh,

[$scratchrule,$ruleheader,$ruletable]]);

$ruletable->configure( -xscrollcommand => [ 'set', $sh]);

$ruleheader->configure( -xscrollcommand => [ 'set', $sh]);

$scratchrule->configure(-xscrollcommand => [ 'set', $sh]);

在这个例子中,$sh是一个横向的滚动条,$ruletable和$scratchrule都是Table,而$ruleheader是一个输入框。

但是,这个例子只是对于需要横向滚动的组件而言的。因此,我想与之相应的纵向滚动应该是这样的:

sub multiscrolly

{ # multiscrolly

my ($sb,$wigs,@args) = @_;

my $w;

foreach $w (@$wigs)

{

$w->yview(@args);

}

} # multiscrolly

# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

$sv->configure( -command => [ \&multiscrolly, $sv,

[$l1,$l2,$l3]]);

$l1->configure( -yscrollcommand => [ 'set', $sv]);

$l2->configure( -yscrollcommand => [ 'set', $sv]);

$l3->configure( -yscrollcommand => [ 'set', $sv]);

希望这些会对大家有所帮助。

Greg VanSickle指出这小段脚本没有提供对于其惯用的’<Button-2>’的绑定。为此,他写了一个叫DSListbox的包来实现这个绑定。

另外,相反的是Jong Park却询问起如何设置用多个滚动条来控制同一个组件的问题。Nick Ing-Simmon的回答是使用一个匿名的子程序。下面就是一个用这种方法来控制一个Text组件的例子(要看到滚动的效果,请在文本框中输入超过20行的文字):

#!/usr/local/bin/perl -w

use Tk;

my $mw = MainWindow->new();

my $s1 = $mw->Scrollbar(-orient => 'vertical');

my $s2 = $mw->Scrollbar(-orient => 'vertical');

$s1->pack(-side => 'left', -fill => 'y');

my $t = $mw->Text(

-yscrollcommand => sub{$s1->set(@_), $s2->set(@_)},

-wrap => 'word',

-width => 70,

-height => 20,

-setgrid => 1,

)->pack(-side => 'left');

$s2->pack(-side => 'right', -fill => 'y');

$s1->configure(-command => [$t => 'yview']);

$s2->configure(-command => [$t => 'yview']);

MainLoop;

__END__

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航