原文:
11.6. How do I use the Canvas as a geometry manager?
In a call to create a window (or anything) on your Canvas you need to specify its position - this is in part how a Canvas can be used as a geometry manager. e.g.: my($bittag) = $canvar->create('bitmap',10,10, -bitmap=>'hourglass');
Specifies the x=10, y=10 screen pixel location (from the upper left). Other possible units are: tag unit example pixels 25,50 # i.e. no unit tag at all m milliimeters 10c,20c c centimeters 1c,2c p points (1/72") 35p,70p
There can be a great deal more to it than just units, however. Note the following question posed and answered by Eric J. Bohm. Eric J. Bohm <bohm@cs.buffalo.edu> wrote: !I've got a row of entries packed side by side in a frame. !These frames are packed on top of each other. !So, when someone deletes a row, the lower ones bubble !up automatically. This works just fine and dandy, and let me !extend my thanks to our brave and energetic pTk team. ! !The trick here is what widget do I put this in so that !it will be scrollable when I have too many rows to !fit on the screen? [details and complaints]
Following up to my own message here.
All right, after several false leads, I spent 3 hours fighting a canvas widget and pounding my head against the canvas.html doc, until I finally understood how to include my entries in a frame in a window in the canvas and get things to scroll nicely.
Turns out that the whole thing isn't all that hard to do once I understood how canvas widgets work.
Not sure if its of general interest, but here's the snippet, which was stolen from the items demo inside the widget_lib and then brutally hacked.
Perhaps a simpler demo would have been easier to use as a guide, but I got there eventually, so my thanks for the widget demo.
#---------------------------------------- my $c = $w_frame->Canvas(); $c->configure( -height => '300', -width => '600', -relief => 'sunken', -bd => 2, ); my $w_frame_vscroll = $w_frame->Scrollbar( -command => ['yview', $c] ); my $w_frame_hscroll = $w_frame->Scrollbar( -orient => 'horiz', -command => ['xview', $c] ); $c->configure(-xscrollcommand => ['set', $w_frame_hscroll]); $c->configure(-yscrollcommand => ['set', $w_frame_vscroll]); $w_frame_hscroll->pack(-side => 'bottom', -fill => 'x'); $w_frame_vscroll->pack(-side => 'right', -fill => 'y'); $c->pack(-expand => 'yes', -fill => 'both',-side=>'top'); my $entryframe=$c->Frame; my $c_win= create $c 'window','0','0', -window=>$entryframe, -anchor=>'nw'; #----------------------------------------
Where $c -> configure( -scrollregion => [$top, $left, $right, $bottom]) can be used to size things nicely once you find out how big it'll be.
And the widgets you want scrolled should be slaves of $entryframe.
Vastly more robust than anything I had running in the BLT Table.
EJB
译文:
11.6. 如何把画布作为布局管理器?
当你在画布里创建一个窗口(或任何其它元件)时,都需要设定它们的位置,而这正是画布作为布局管理器的作用。例如:
my($bittag) = $canvar->create('bitmap',10,10, -bitmap=>'hourglass');
这里,就指定了这个位图在屏幕上的坐标(象素)是x=10,y=10(从左上角开始)。
其它可能的坐标单位还有:
符号 单位 例子
象素 25,50 #也就是不用写任何单位量
m 毫米 10m,20m
c 厘米 1c,2c
p 点(1/72英寸) 35p,70p
当然,作为布局管理器,绝不仅仅是坐标的单位而已。让我们看看下面的这个由Eric J. Bohm提出并回答的问题:
Eric J. Bohm写到:
!我在一个框架中设置了一列连续的输入框,自上而下排列。
!这样,当删除了其中的一个时,下面的会自动的冒上来。
!这个工作实在是太好了,我要感谢咱们积极勇敢的pTk开发小组!
!
!现在我遇到的麻烦是,我应该把我设计的这套东西放在什么组件中,
!才能使得当我有很多行,超出了屏幕的范围时,它可以带有滚动条?
[细节和抱怨……]
下面是我自己的解决方案:(译者注:这里的“我”还是指Eric J. Bohm)
经过几次失败的尝试,我又花了3个小时研究了画布组件和canvas.html的文档,直到我最后终于明白了如何把我的一系列输入框放入到一个框架中,然后作为一个窗口放入画布里,这样就可以让他滚动起来了。
现在我感觉其实这个事情并没有那么困难,只要我们理解了画布组件是如何工作的。
虽然我还是不太确定是否会有很多人对这个感兴趣,但我还是在这里放了一个小片断——是从widget_lib里的演示脚本中摘录下来的。
也许如果有个简单些的演示程序来作为向导会让这些变得更容易一些吧,不过我最终还是找到了,所以还是要感谢widget演示程序。
#----------------------------------------
my $c = $w_frame->Canvas();
$c->configure(
-height => '300',
-width => '600',
-relief => 'sunken',
-bd => 2,
);
my $w_frame_vscroll = $w_frame->Scrollbar(
-command => ['yview', $c]
);
my $w_frame_hscroll = $w_frame->Scrollbar(
-orient => 'horiz',
-command => ['xview', $c]
);
$c->configure(-xscrollcommand => ['set', $w_frame_hscroll]);
$c->configure(-yscrollcommand => ['set', $w_frame_vscroll]);
$w_frame_hscroll->pack(-side => 'bottom', -fill => 'x');
$w_frame_vscroll->pack(-side => 'right', -fill => 'y');
$c->pack(-expand => 'yes', -fill => 'both',-side=>'top');
my $entryframe=$c->Frame;
my $c_win= create $c 'window','0','0',
-window=>$entryframe,
-anchor=>'nw';
#----------------------------------------
这里$c -> configure( -scrollregion => [$top, $left, $right, $bottom])可以用来在你知道了组件的大小以后来设置其尺寸。
这样,你想要可以滚动的组件必须是从属于$entryframe的。
非常好用,比我曾经用过的BLT Table要强壮的多。
EJB