Обзор Gtk-Perl | ||
---|---|---|
Предыдущая | Следующая |
Object
+--- Widget
+--- Container
+--- Box
При создании приложения, вам будет необходимо расположить более одного виджета на формочке, ооветственной за все приложение. В первом примере была всего одна кнопка, и поэтому можно было использовать простую конструкцию $window->add() чтобы поместить виджет в окно. Но когда нужно поместить более одного виджета, необходимо их позиционировать относительно друг друга, с тем чтобы создать некий интерфейс к создаваемому Вами приложению.
Packing boxes - невидимые widget контейнеры, в которых располагаются вджеты. Packing boxes имееют две формы: горизонтальную и вертикальную. При помещении widgets в горизонтальный бокс, объекты вставлены горизонтально слева направо или наоборот в зависимости от используемого запроса. В вертикальном боксе, widgets упакованы сверху донизу или наоборот. Вы можете использовать любую комбинацию боксов для расположения виджетов внутри или рядом с двругими Packing boxes, чтобы придать желательные эффект и дизайн вашему приложению.
Для создания нового горизонтального или вертикального бокса, нужно написать
следующие строчки:
$hbox = new Gtk::HBox( $homogeneous, $spacing );
$vbox = new Gtk::VBox( $homogeneous, $spacing );
$box->pack_start( $child, $expand, $fill, $padding );
$box->pack_end( $child, $expand, $fill, $padding );
Если переменная $homogeneous
, то виждет можно располагать в пределах, определяемых HBox и Vbox.
Переменная $spacing
определяет границу в пикселах, на которую отстоят виджеты друг от друга.
Следующие функции используются для расположения объектов внутри бокса:
Функция
pack_start()
располагает элементы списка сверху в VBox и соответственно в слева направо в
HBox. Действие функции
pack_end() противоположно действию pack_start().
Добавленный объект может быть другим контейнером, например много виджетов -
те-же самые контейнеры, за исключением что в таких случаях как правло
используются либо pixmaps либо кнопки. Расположенный виджет в боксе является
дочерним к этому боксу.
Если аргумент $expand истеннен, то виджеты расположены в боксе так, что заполняют все место, если аргумент ложен, то бокс сокращается до размера виджета. Присваивая параметру расширения ложное значение виждет будет выравниваться по левому или правому краю в зависимости от желания. Следует отметить, что присваивание переменной $homogeneous значения true аналогично присваиванию значения ture переменной $expand
Если аргумент $fill истеннен, тогда дополнительное место распределено между объектами. В другом случае дополнительное свободное место распределяется между виджетами. Такое распределение возможно когда $expand выставлен в положение true.
Используя данные вариации, Gtk знает, где Вы хотите разместить ваш widgets, и автоматически может изменять размер виджета и другие изящные вещи. Вобщем использование данного метода дает немного гибкости при размещении и создании widgets.
Из-за этой гибкости боксы в GTK могут быть немного запутанны. Есть много различных способов расположения виджетов и не сразу очевидно, как они взаимодействуют между собой. В основном есть 5 различных стилей размещения, примеры которых приведены ниже:
Packing Box Styles Screenshot
Каждая линия примера содержит один горизонтальный бокс с несколькими кнопками. Запрос pack записывается для каждого pack отвечающего за кнопку внутри hbox. Каждая из кнопок помещается в hbox различными способами(то есть, те же самые аргументы подходят для функции pack_start()).
Метод является быстрым вызовом из
pack_start()
и
pack_end(),
которые устанавливают растягивающую виджет переменную в true, заполняют её и
устанавливают переменную в 0:
$box->pack_start_defaults( $widget );
$box->pack_end_defaults( $widget );
Однотипная(homogeneous) переменная бокса, в котором располагаются виджеты, может быть
установлена в on или off при помощи следующей функции:
$box->set_homogeneous( $homogeneous );
Переменная устанваливающая отступы вокруг виджета, может быть установлена
при помощи функции
$box->set_spacing( $spacing );
Если Вы хотите перестить потомка на новое место, то нужно использовать
функцию
$box->reorder_child( $child, $position );
где
$child
- перемещаемый виджет и
$position
- позиция для перемещения, начиная с 0. Если Вы хотите рассмотреть текущий
порядок, то нежно смотреть на список, возвращаемый функцией
children()
(унаследованной от Container).
Если необходимо изменить установку потомка, то используется следующая
функция:
$box->set_child_packing( $widget, $expand, $fill, $padding, $pack_type );
Аргументы этой функции похожи на аргументы
pack_start()
и
pack_end(),
за исключением
$pack_type,
которая может принимать значения либо 'start' либо 'end'. Каково различие
между интервалом и дополнением? Интервал добавлен между объектами, а
дополнение добавлено с обоих сторон объекта. Приведенная картинка поясняет
сказанное более ясно:
Packing Box Spacing Screenshot
Приведенная ниже программа показывает, как реализовать некоторые из типов расположения структур в приложении:
#!/usr/bin/perl -w use Gtk; use strict; set_locale Gtk; init Gtk; unless ($ARGV[0]){ print( "Использование: выберите тип расположения 1, 2, или 3.\n" ); Gtk->exit( 1 ); exit( 1 ); } my $false = 0; my $true = 1; my $which = $ARGV[0]; my ($window,$box1,$box2,$label,$separator,$quitbox,$button); # Вы должны всегда определять обработчик сигнала # delete_event для основного окна # Это очень важно для верного поведения програмы в случае сбоев $window = new Gtk::Window( "toplevel" ); $window->signal_connect( "delete_event", sub { Gtk->exit( 0 ); } ); $window->border_width( 10 ); # Мы создаем вертикальный бокс(vbox), и затем в него # ставим горизонтальные боксы. Такое расположение позволяет # расставлять горизонтальные боксы, заполненные кнопками, один над другим $box1 = new Gtk::VBox( $false, 0 ); # какой пример, соответствующий изображениям выше, показывать if ( $which == 1 ) { # создаем новый лейбл. $label = new Gtk::Label( 'new Gtk::HBox( $false, 0 );' ); # Выравниваем его по левой стороне. Описание этой функции ниже. $label->set_alignment( 0, 0 ); # Поместить лейбл в вертикальный бокс(vbox box1). Запомните, что # эти виджеты добавляются в vbox, который будет расположен свеху # остальных $box1->pack_start( $label, $false, $false, 0 ); # показываем лейбл $label->show(); # запрашиваем нашу создаваемую box функцию # homogeneous = FALSE, spacing = 0, # expand = FALSE, fill = FALSE, padding = 0 $box2 = make_box( $false, 0, $false, $false, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # запрашиваем создающую бокс функцию # homogeneous = FALSE, spacing = 0, # expand = TRUE, fill = FALSE, padding = 0 $box2 = make_box( $false, 0, $true, $false, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Аргументы следующие: homogeneous, spacing, expand, fill, padding $box2 = make_box( $false, 0, $true, $true, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Создаем разделитель, описание позднее. $separator = new Gtk::HSeparator(); # Устанавливаем сепаратор в vbox, помните, # что каждый из этих widgets упаковывается в vbox, # так что они будут сложены вертикально $box1->pack_start( $separator, $false, $true, 5 ); $separator->show(); # Создаем другой лейбл и показываем $label = new Gtk::Label( 'new Gtk::HBox( $true, 0 );' ); $label->set_alignment( 0, 0 ); $box1->pack_start( $label, $false, $false, 0 ); $label->show(); # Аргументы: homogeneous, spacing, expand, fill, padding $box2 = make_box( $true, 0, $true, $false, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Аргументы: homogeneous, spacing, expand, fill, padding $box2 = make_box( $true, 0, $true, $true, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Другой новый сепаратор. $separator = new Gtk::HSeparator(); # Последние три аргумента gtk_box_pack_start: $separator = new Gtk::HSeparator(); # Последние три аргумента gtk_box_pack_start: # expand, fill, padding. $box1->pack_start( $separator, $false, $true, 5 ); $separator->show(); } elsif ( $which == 2 ) { # Создаем новый лейбл, запомните, что box1 это vbox $label = new Gtk::Label( 'new Gtk::HBox( $false, 10 );' ); $label->set_alignment( 0, 0 ); $box1->pack_start( $label, $false, $false, 0 ); $label->show(); # Аргументы: homogeneous, spacing, expand, fill, padding $box2 = make_box( $false, 10, $true, $false, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Аргументы: homogeneous, spacing, expand, fill, padding $box2 = make_box( $false, 10, $true, $true, 0 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); $separator = new Gtk::HSeparator(); # Последние три аргумента gtk_box_pack_start: expand, fill, # и padding. $box1->pack_start( $separator, $false, $true, 5 ); $separator->show(); $label = new Gtk::Label( 'new Gtk::HBox( $false, 0 );' ); $label->set_alignment( 0, 0 ); $box1->pack_start( $label, $false, $false, 0 ); $label->show(); # Аргументы: homogeneous, spacing, expand, fill, padding $box2 = make_box( $false, 0, $true, $false, 10 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Аргументы: homogeneous, spacing, expand, fill, padding $box2 = make_box( $false, 0, $true, $true, 10 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); $separator = new Gtk::HSeparator(); # Последние три аргумента: expand, fill, # и padding. $box1->pack_start( $separator, $false, $true, 5); $separator->show(); } elsif ( $which == 3 ) { # этот пример показывает, как pack_end() выравнивает # widgets по правому краю. Создаем новый box. $box2 = make_box( $false, 0, $false, $false, 0); # Создаем новый лейбл, который будет установлен в конец. $label = new Gtk::Label( "end" ); # Установка с применением gtk_box_pack_end(), $box2->pack_end( $label, $false, $false, 0 ); # показываем лейбл. $label->show(); # Помещаем box2 в box1 $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); # Сепаратор снизу $separator = new Gtk::HSeparator(); # далее подробно устанавливаем параметры разделителя # в 400 пикселов и ширинойц и 5 пикселов высотой # так-же это значит, что hbox быдет создан шириной в 400 пикселов # и ярлык "end" будет отделен от других лейблов в hbox. # В противном случае все лейблы будут прилегать друг к другу вплотную $separator->set_usize( 400, 5 ); # добавить сепаратор в vbox(box1), созданный вначале программы $box1->pack_start( $separator, $false, $true, 5 ); $separator->show(); } # создать другой бокс, $quitbox = new Gtk::HBox( $false, 0 ); # создаем кнопку выход. $button = new Gtk::Button( "Quit" ); # Послать сигнал для завершения программы, когда кнопка будет нажата $button->signal_connect( "clicked", sub { Gtk->exit( 0 ); } ); # Добавить кнопку в quitbox # последние три аргумента gtk_box_pack_start: # expand, fill, padding. $quitbox->pack_start( $button, $true, $false, 0 ); # добавить quitbox в vbox (box1) $box1->pack_start( $quitbox, $false, $false, 0 ); # Добавить vbox(box1) который теперь содержит все наши виджеты в основное окно $window->add( $box1 ); # и показать все слева $button->show(); $quitbox->show(); $box1->show(); # Показ всего окна со всеми лейблами и кнопками. $window->show(); # вызов основной функции. main Gtk; exit(0); # создаем новый hbox, заполненный кнопками и лейбралми. # Мы не показываем сам бокс, но показываем его содержимое sub make_box{ my ($homogeneous,$spacing,$expand,$fill,$padding) = @_; # создаем новый hbox с соответствующими установками типов и отступов my $box = new Gtk::HBox( $homogeneous, $spacing ); $button = new Gtk::Button( '$box->' ); $box->pack_start( $button, $expand, $fill, $padding ); $button->show(); # Create a series of buttons with the appropriate settings # Создаем серию кнопок с соответствующими настройками $button = new Gtk::Button( "pack" ); $box->pack_start( $button, $expand, $fill, $padding ); $button->show(); $button = new Gtk::Button( '( $button,' ); $box->pack_start( $button, $expand, $fill, $padding ); $button->show(); # создаем кнопку с лейблом, зависящим от переменной, отвечающей за растягивание if ($expand){ $button = new Gtk::Button('$true,'); } else { $button = new Gtk::Button('$false,'); } $box->pack_start( $button, $expand, $fill, $padding ); $button->show(); if ( $fill ) { $button = new Gtk::Button( '$true,' ); } else { $button = new Gtk::Button( '$false,' ); } $box->pack_start( $button, $expand, $fill, $padding ); $button->show(); $button = new Gtk::Button( "$padding );" ); $box->pack_start( $button, $expand, $fill, $padding ); $button->show(); return ( $box ); }
Предыдущая | Начало | Следующая |
Основные контейнеры | Вверх | Таблицы |