|
Виды сайзеров
Продолжаем
изучение схем расстановки виджетов с помощью сайзеров. На предыдущем занятии мы
с вами рассмотрели построение интерфейса с использованием BoxSizer, далее
поговорим о GridSizer.
GridSizer
Он позволяет
создавать двумерную сетку ячеек с одинаковой шириной и одинаковой высотой.
Общий синтаксис следующий:
wx.GridSizer(rows=1,
cols=0, vgap=0, hgap=0)
-
rows – число строк
(отсчет начинается с 1);
-
cols – число
столбцов (отсчет идет с 0);
-
vgap – интервал
между ячейками по вертикали;
-
hgap – интервал
между ячейками по горизонтали.
Давайте в
качестве примера создадим вот такой импровизированный калькулятор:
Вначале создадим
BoxSizer с вертикальным
расположением элементов:
vbox = wx.BoxSizer(wx.VERTICAL)
И в первой
ячейке разместим поле ввода:
tc = wx.TextCtrl(panel)
vbox.Add(tc, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)
Вторая ячейка
будет содержать сайзер:
gbox = wx.GridSizer(5, 4, 5, 5)
состоящий из 5
строк и 4 столбцов. Расстояния между ячейками 5 пикселей по горизонтали и по
вертикали. Помещаем в этот сайзер все необходимые кнопки:
gbox.AddMany([ (wx.Button(panel, label='Cls'), 0, wx.EXPAND),
(wx.Button(panel, label='Bck'), 0, wx.EXPAND),
(wx.StaticText(panel), wx.EXPAND),
(wx.Button(panel, label='Close'), 0, wx.EXPAND),
(wx.Button(panel, label='7'), 0, wx.EXPAND),
(wx.Button(panel, label='8'), 0, wx.EXPAND),
(wx.Button(panel, label='9'), 0, wx.EXPAND),
(wx.Button(panel, label='/'), 0, wx.EXPAND),
(wx.Button(panel, label='4'), 0, wx.EXPAND),
(wx.Button(panel, label='5'), 0, wx.EXPAND),
(wx.Button(panel, label='6'), 0, wx.EXPAND),
(wx.Button(panel, label='*'), 0, wx.EXPAND),
(wx.Button(panel, label='1'), 0, wx.EXPAND),
(wx.Button(panel, label='2'), 0, wx.EXPAND),
(wx.Button(panel, label='3'), 0, wx.EXPAND),
(wx.Button(panel, label='-'), 0, wx.EXPAND),
(wx.Button(panel, label='0'), 0, wx.EXPAND),
(wx.Button(panel, label='.'), 0, wx.EXPAND),
(wx.Button(panel, label='='), 0, wx.EXPAND),
(wx.Button(panel, label='+'), 0, wx.EXPAND) ])
Там где кнопки
нет идет текстовый элемент без содержимого. Каждая кнопка привязана к панели и
занимает весь допустимый размер (флаг EXPAND).
Добавляем этот
объект во вторую ячейку сайзера vbox с отступами 10 пикселей с каждой
стороны:
vbox.Add(gbox, flag=wx.EXPAND | wx.ALL, border=10)
Запускаем
программу и видим результат. Но здесь есть один недостаток: когда мы меняем
окно по вертикали кнопки остаются неизменными. Исправим это, добавив свойство proportion=1:
vbox.Add(gbox, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
Теперь интерфейс
занимает все доступное пространство. Вот так работает GridSizer.
FlexGridSizer
Следующий FlexGridSizer работает
аналогично GridSizer, но в отличие
от предыдущего здесь ширина (или высота) у соответствующих групп ячеек может
быть разная.
Давайте
представим, что мы делаем форму для ввода регистрационной информации
пользователя и она должна выглядеть вот так:
Для начала
создадим такой сайзер с 4 строками, 2 столбцами и расстояниями между ячейками
10 пикселей:
fb = wx.FlexGridSizer(4, 2, 10, 10)
Далее, используя
уже знакомый метод AddMany() добавим все виджеты в данный объект:
fb.AddMany([ (wx.StaticText(panel, label="Ф.И.О.:")),
(wx.TextCtrl(panel), wx.ID_ANY, wx.EXPAND),
(wx.StaticText(panel, label="email:")),
(wx.TextCtrl(panel), wx.ID_ANY, wx.EXPAND),
(wx.StaticText(panel, label="Адрес:")),
(wx.TextCtrl(panel), wx.ID_ANY, wx.EXPAND),
(wx.StaticText(panel, label="О себе:")),
(wx.TextCtrl(panel, style=wx.NB_MULTILINE), wx.ID_ANY, wx.EXPAND)
])
И
свяжем панель с этим сайзером:
Запустим
программу и увидим вот такой результат:
Кажется это не
то, что мы бы хотели. Для начала укажем, что второй столбец следует расширять
по максимуму. Воспользуемся методом:
AddGrowableCol(self, col, proportion=0)
и через него
зададим proportion=1 для второго
столбца (col=1), получим:
Теперь все наши
текстовые элементы достигают конца окна. Далее, вот этот последний элемент с
текстом «О себе» следует расширить до нижней границы окна. Это можно сделать с
помощью похожего метода:
AddGrowableRow(self, row, proportion=0)
и для row=3 укажем proportion=1:
Все, теперь наши
виджеты выглядят так, как этого мы и хотим. Но нам нужны еще отступы от границ
окна. Для этого мы поместим сайзер fb в другой сайзер BoxSizer и уже в нем
укажем необходимые отступы:
hbox = wx.BoxSizer()
hbox.Add(fb, proportion=1, flag=wx.EXPAND|wx.ALL, border=10)
Свяжем панель с этим
новым объектом:
и получим
желаемый результат.
GridBagSizer
Это, наверное, самый
гибкий сайзер среди всех в wxPython. Он динамически создает таблицу
ячеек, у которых могут быть разные размеры (также как и у FlexGridSizer). При его создании,
мы указываем только два параметра:
GridBagSizer(vgap,
hgap)
расстояния между
ячейками в пикселах. А, затем, вызывая метод:
Add(self,
item, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)
можем добавлять
виджет в позицию
pos=(row, col)
где указываем
нужную строку и столбец. При этом сайзер автоматически добавит нужное
количество ячеек, чтобы формировалась таблица из соответствующего числа строк и
столбцов. А благодаря параметру span мы можем задавать ячейки, охватывающие
сразу несколько соседних ячеек. Например, давайте создадим вот такое окно:
И расположим все
эти виджеты вот в такой сетке:
Ее мы как раз и
создадим с помощью GridBagSizer. Создадим его:
gr = wx.GridBagSizer(5, 5)
Мы здесь
указываем отступы между ячейками в 5 пикселей. Далее, создадим текстовый
виджет:
text = wx.StaticText(panel, label="Email:")
и добавим его в
первую ячейку:
gr.Add(text, pos=(0, 0), flag=wx.TOP | wx.LEFT | wx.BOTTOM, border=5)
Смотрите, здесь
параметр pos=(0,0) как раз и
указывает первую строку и первый столбец, т.е. первую ячейку нашего сайзера.
Создадим
текстовое поле ввода:
и добавим его во
вторую строку и так, чтобы он охватывал 5 ячеек по столбцам:
gr.Add(tc, pos=(1, 0), span=(1, 5), flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)
Это делается
через параметры pos=(1,0) и span(1,5). Последний
означает, что мы будем захватывать одну строку и 5 столбцов. Как раз получим
единую горизонтальную ячейку нашей таблицы.
Далее создаем
две кнопки:
button1 = wx.Button(panel, label="Восстановить", size=(120, 28))
button2 = wx.Button(panel, label="Отмена", size=(90, 28))
и добавляем их в
четвертую строку и 4-е, 5-е ячейки (не забываем, что отсчет идет с нуля):
gr.Add(button1, pos=(3, 3))
gr.Add(button2, pos=(3, 4), flag=wx.RIGHT|wx.BOTTOM, border=10)
Осталось связать
наш сайзер с панелью:
и запустить
программу. Смотрите, ячейки не распахиваются на все окно, а группируются
вначале:
Поправим это.
Во-первых, сделаем второй столбец максимальным по ширине. Для этого
воспользуемся методом
класса
GridBagSizer
AddGrowableCol(col)
в котором
указывается столбец для масштабирования. В нашем случае запишем строчку:
Запустим
программу и видим, что теперь все растягивается по ширине, как и задумывалось.
По аналогии растянем по высоте третью строку с помощью похожего метода:
AddGrowableRow(row)
получим:
Теперь наш
интерфейс выглядит в полном соответствии с задумкой.
Итак, на этом и
предыдущем занятиях мы с вами рассмотрели принципы размещения виджетов с
разными схемами расположения, используя сайзеры:
BoxSizer,
GridSizer,
FlexGridSizer, GridBagSizer
Все их можно
комбинировать и получать самые разные варианты схем расположения элементов управления
в пределах окна. Конечно, это не все сайзеры, существующие в wxPython. Полное
описание этого функционала вы уже знаете где смотреть, на официальном сайте:
https://docs.wxpython.org
|