2015-10-01 2 views
2

Использование Perl Tkx, я пытаюсь создать окно с виджетами treeview и панель прокрутки справа от нее. Мне нужен виджет treeview для автоматического изменения размера, когда пользователь изменяет размер окна.Как добиться видоизмененного виджета виджета с полосой прокрутки в Perl Tkx?

Это то, что у меня есть:

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']); 

Оба виджеты отображаются в окне, и изменение размера работы, но, к сожалению, полоса прокрутки находится под дерево, а не справа от нее. Если я удалю три строки g_pack(-expand => 1, -fill => 'both'), позиционирование будет правильным, но изменение размера не будет выполнено. Как разместить полосу прокрутки справа от дерева и выполнить автоматическое изменение размера?

+0

Вы связаны с Tk? Классическим решением является установка как дерева, так и полосы прокрутки в рамке контейнера. Будет ли это работать на вас? – Borodin

ответ

3

Вы используете как grid, так и pack для виджетов виджета в один и тот же контейнер, который не поддерживается. Первым шагом будет использование только pack везде, поскольку у вас есть простая компоновка для виджетов.

Использование -expand => 1 для полосы прокрутки означает, что Tk попытается предоставить как можно больше места. Вы не хотите, чтобы для полосы прокрутки, поскольку она должна быть выделена достаточно места для себя. Я изменил -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 книги, особенно раздел о менеджере pack геометрии. В этой книге используется Tk module, а не Tkx, но я думаю, что должно быть легко сопоставить понятия между ними.

3

В вашем приложении можно использовать несколько менеджеров геометрии, но вы не можете их смешивать при организации дочерних элементов определенного виджета. Здесь будет работать pack или grid; вам нужно выбрать один и придерживаться его.

При использовании pack вам необходимо указать сторону родительского контейнера, на которой будет установлен виджет. (По умолчанию top, если не указано). Поскольку вы хотите разместить свое дерево и полосу прокрутки бок о бок, используйте left. Вы хотите, чтобы полоса прокрутки заполнила доступное вертикальное пространство. Вы не хотите, чтобы он заполнял горизонтальное пространство. При упаковке меняйте -fill от both до 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 сделать виджеты расширить, чтобы заполнить свои ячейки и настройки строк/столбцов, чтобы определить, как они должны реагировать на изменение размера. Вы хотите, чтобы дерево придерживалось со всех сторон (nsew) и полоса прокрутки, чтобы придерживаться сверху и снизу (ns). Дерево должно быть ячейкой, которая заявляет о наличии свободного пространства при изменении размера, поэтому мы настраиваем его ячейку на 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 проще.