如何在 Perl Tkx 中实现带滚动条的可调整大小的树视图小部件?

How to achieve a resizable treeview widget with scrollbar in Perl Tkx?

我正在尝试使用 Perl Tkx 创建一个 window,其中包含树视图小部件和右侧的滚动条。我需要树视图小部件在用户调整 window.

大小时自动调整大小

这是我的:

my $mw = Tkx::widget->new(".");

my $frm = $mw->new_ttk__frame(-padding => "2 6 12 12");
$frm->g_grid(-column => 0, -row => 0, -sticky => "nwes");
$frm->g_pack(-expand => 1, -fill => 'both');

my $tree = $frm->new_ttk__treeview;
$tree->g_grid(-column => 1, -columnspan => 5, -row => 1, -sticky => "we");
$tree->g_pack(-expand => 1, -fill => 'both');

my $scrollbar = $frm->new_ttk__scrollbar(-orient => 'vertical', -command => [$tree, 'yview']);
$scrollbar->g_grid(-column => 6, -row => 1, -sticky => "we");
$scrollbar->g_pack(-expand => 1, -fill => 'both');

$tree->configure(-yscrollcommand => [$scrollbar, 'set']);

两个小部件都显示在 window 中,并且调整大小有效,但不幸的是,滚动条位于树 下方 下,而不是右侧。如果我删除三个 g_pack(-expand => 1, -fill => 'both') 行,定位是正确的,但调整大小不起作用。如何将滚动条放在树的右侧,并使自动调整大小起作用?

您同时使用 gridpack 将小部件布局到同一个容器中,这是不受支持的。第一步是在任何地方只使用 pack,因为你对小部件的安排很简单。

对滚动条使用 -expand => 1 意味着 Tk 会尽可能多地给它 space。您不希望滚动条使用它,因为它只应为其自身分配足够 space 的空间。我已将 -fill 更改为 'y' 作为样式问题,但似乎没有太大区别。

$scrollbar->g_pack(-expand => 0, -fill => 'y');

pack 默认情况下会将小部件一个接一个地排列。所以,如果你需要从左边开始水平排列,你应该添加一个-side参数:

$tree->g_pack(-expand => 1, -fill => 'both', -side => 'left');
$scrollbar->g_pack(-expand => 0, -fill => 'y', -side => 'left');

我建议您通读优秀的 Mastering Perl/Tk book, especially the section about the pack geometry manager. This book uses the Tk module 而不是 Tkx,但我认为在两者之间映射概念应该很容易。

在您的应用程序中使用多个几何管理器是可以的,但您不能在安排特定小部件的子项时混合使用它们。 packgrid 都可以在这里工作;你需要选择一个并坚持下去。

使用 pack 时,您需要指定在父容器的哪一侧打包小部件。 (如果未指定,默认值为 top)。因为你想并排放置你的树和滚动条,所以使用 left。您只希望滚动条填充可用的垂直 space。您不希望它水平填充 space。打包时将 -fillboth 更改为 y 并删除 -expand(或将其设置为 0)。

use Tkx;
my $mw = Tkx::widget->new(".");

my $frm = $mw->new_ttk__frame(-padding => "2 6 12 12");
$frm->g_pack(-expand => 1, -fill => 'both');

my $tree = $frm->new_ttk__treeview;
$tree->g_pack(-side => 'left', -expand => 1, -fill => 'both');

my $scrollbar = $frm->new_ttk__scrollbar(-orient => 'vertical', -command => [$tree, 'yview']);
$scrollbar->g_pack(-side => 'left', -fill => 'y');

$tree->configure(-yscrollcommand => [$scrollbar, 'set']);

Tkx::MainLoop();

如果您选择使用 grid,则需要设置 sticky 以使小部件扩展以填充其单元格,并配置 rows/columns 以定义它们应如何响应调整大小。您希望树粘在所有边上 (nsew),滚动条粘在顶部和底部 (ns)。树应该是在调整大小时声明可用 space 的单元格,因此我们将其单元格配置为 weight 为 1,并使用默认权重为零的滚动条保留单元格。

use Tkx;
my $mw = Tkx::widget->new(".");

my $frm = $mw->new_ttk__frame(-padding => "2 6 12 12");
$frm->g_pack(-expand => 1, -fill => 'both');

my $tree      = $frm->new_ttk__treeview;
my $scrollbar = $frm->new_ttk__scrollbar(-orient => 'vertical', -command => [$tree, 'yview']);

$tree->g_grid(-row => 0, -column => 0, -sticky => "nsew");
$scrollbar->g_grid(-row => 0, -column => 1, -sticky => "ns");

$frm->g_grid_columnconfigure(0, -weight => 1);
$frm->g_grid_rowconfigure(0, -weight => 1);

$tree->configure(-yscrollcommand => [$scrollbar, 'set']);

Tkx::MainLoop();

请注意,我仍在使用 pack 来管理父框架并告诉它向两个方向扩展。如果父框架不展开其中的小部件,它也不能。我本可以使用 grid 管理框架,但使用 pack 更简单。