Основы Tk
Основная черта любой программы с графическим интерфейсом — интерактивность. Программа не просто что–то считает (в пакетном режиме) от начала своего запуска до конца: ее действия зависят от вмешательства пользователя. Фактически, графическое приложение выполняет бесконечный цикл обработки событий. Программа, реализующая графический интерфейс, событийно–ориентирована. Она ждет от интерфейса событий, которые и обрабатывает сообразно своему внутреннему состоянию.
Эти события возникают в элементах графического интерфейса (виджетах) и обрабатываются прикрепленными к этим виджетам обработчиками. Сами виджеты имеют многочисленные свойства (цвет, размер, расположение), выстраиваются в иерархию принадлежности (один виджет может быть хозяином другого), имеют методы для доступа к своему состоянию.
Расположением виджетов (внутри других виджетов) ведают так называемые менеджеры расположения. Виджет устанавливается на место по правилам менеджера расположения. Эти правила могут определять не только координаты виджета, но и его размеры. В Tk имеются три типа менеджеров расположения: простой упаковщик (pack), сетка (grid) и произвольное расположение (place).
Но этого для работы графической программы недостаточно. Дело в том, что некоторые виджеты в графической программе должны быть взаимосвязаны определенным образом. Например, полоска прокрутки может быть взаимосвязана с текстовым виджетом: при использовании полоски текст в виджете должен двигаться, и наоборот, при перемещении по тексту полоска должна показывать текущее положение. Для связи между виджетами в Tk используются переменные, через которые виджеты и передают друг другу параметры.
Классы виджетов
Для построения графического интерфейса в библиотеке Tk отобраны следующие классы виджетов (в алфавитном порядке):
Button (Кнопка) Простая кнопка для вызова некоторых действий (выполнения определенной команды).
Canvas (Рисунок) Основа для вывода графических примитивов.
Checkbutton (Флажок) Кнопка, которая умеет переключаться между двумя состояниями при нажатии на нее.
Entry (Поле ввода) Горизонтальное поле, в которое можно ввести строку текста.
Frame (Рамка) Виджет, который содержит в себе другие визуальные компоненты.
Label (Надпись) Виджет может показывать текст или графическое изображение.
Listbox (Список) Прямоугольная рамка со списком, из которого пользователь может выделить один или несколько элементов.
Menu (Меню) Элемент, с помощью которого можно создавать всплывающие (popup) и ниспадающие (pulldown) меню.
Menubutton (Кнопка–меню) Кнопка с ниспадающим меню.
Message (Сообщение) Аналогично надписи, но позволяет заворачивать длинные строки и менять размер по требованию менеджера расположения.
Radiobutton (Селекторная кнопка) Кнопка для представления одного из альтернативных значений. Такие кнопки, как правило, действует в группе. При нажатии на одну из них кнопка группы, выбранная ранее, «отскакивает».
Scale (Шкала) Служит для задания числового значения путем перемещения движка в определенном диапазоне.
Scrollbar (Полоса прокрутки) Полоса прокрутки служит для отображения величины прокрутки в других виджетах. Может быть как вертикальной, так и горизонтальной.
Text (Форматированный текст) Этот прямоугольный виджет позволяет редактировать и форматировать текст с использованием различных стилей, внедрять в текст рисунки и даже окна.
Toplevel (Окно верхнего уровня) Показывается как отдельное окно и содержит внутри другие виджеты.
Все эти классы не имеют отношений наследования друг с другом — они равноправны. Этот набор достаточен для построения интерфейса в большинстве случаев.
События
В системе современного графического интерфейса имеется возможность отслеживать различные события, связанные с клавиатурой и мышью, и происходящие на «территории» того или иного виджета. В Tk события описываются в виде текстовой строки — шаблона события, состоящего из трех элементов (модификаторы, тип события и детализация события).
Тип события Содержание события
Activate Активизация окна
ButtonPress Нажатие кнопки мыши
ButtonRelease Отжатие кнопки мыши
Deactivate Деактивация окна
Destroy Закрытие окна
Enter Вхождение курсора в пределы виджета
FocusIn Получение фокуса окном
FocusOut Потеря фокуса окном
KeyPress Нажатие клавиши на клавиатуре
KeyRelease Отжатие клавиши на клавиатуре
Leave Выход курсора за пределы виджета
Motion Движение мыши в пределах виджета
MouseWheel Прокрутка колесика мыши
Reparent Изменение родителя окна
Visibility Изменение видимости окна
Примеры описаний событий строками и некоторые названия клавиш приведены ниже:
"<ButtonPress–3>" или просто "<3>" — щелчок правой кнопки мыши (то есть, третьей, если считать на трехкнопочной мыши слева–направо). "<Shift–Double–Button–1>" — двойной щелчок мышью (левой кнопкой) с нажатой кнопкой Shift. В качестве модификаторов могут быть использованы следующие (список неполный):
Листинг
Control, Shift, Lock,
Button1–Button5 или B1–B5,
Meta, Alt, Double, Triple.
Просто символ обозначает событие — нажатие клавиши. Например, «k» — тоже, что "<KeyPress–k>". Для неалфавитно–цифровых клавиш есть специальные названия:
Листинг
Cancel, BackSpace, Tab, Return, Shift_L, Control_L, Alt_L,
Pause, Caps_Lock, Escape, Prior, Next, End, Home, Left,
Up, Right, Down, Print, Insert, Delete, F1, F2, F3, F4, F5, F6, F7,
F8, F9, F10, F11, F12, Num_Lock, Scroll_Lock, space, less
Здесь <space> обозначает пробел, а <less> - знак меньше. <Left>, <Right>, <Up>, <Down> - стрелки. <Prior>, <Next> - это PageUp и PageDown. Остальные клавиши более или менее соответствуют надписям на стандартной клавиатуре.
Примечание:
Следует заметить, что Shift_L, в отличие от Shift, нельзя использовать как модификатор.
В конкретной среде комбинации, означающие что–то особенное в системе, могут не дойти до графического приложения. Например, известный всем Ctrl–Alt–Del.
Следующая программа позволяет печатать направляемые виджету события, в частности — keysym, а также анализировать, как различные клавиши можно представить в шаблоне события:
Листинг
from Tkinter import *
tk = Tk() # основное окно приложения
txt = Text(tk) # текстовый виджет, принадлежащий окну tk
txt.pack() # располагается менеджером pack
# функция обработки события
def event_info(event):
txt.delete(«1.0», END) # удаляется с начала до конца текста
for k in dir(event): # цикл по атрибутам события
if k[0] != "_": # берутся только неслужебные атрибуты
# готовится описание атрибута события
ev = "%15s: %s\n» % (k, repr(getattr(event, k)))
txt.insert(END, ev) # добавляется в конец текста
# привязывается виджету txt функция event_info для обработки событий,
# соответствующих шаблону <KeyPress>
txt.bind("<KeyPress>", event_info)
tk.mainloop() # главный цикл обработки событий
При нажатии клавиши Esc в окне можно увидеть примерно следующее:
Листинг
char: '\x1b'
delta: 9
height: 0
keycode: 9
keysym: 'Escape'
keysym_num: 65307
num: 9
send_event: False
serial: 159
state: 0
time: — 1072960858
type: '2'
widget: <Tkinter.Text instance at 0x401e268c>
width: 0
x: 83
x_root: 448
y: 44
y_root: 306
Следует объяснить некоторые из этих атрибутов:
char Нажатый символ (для некоторых событий - ??)
height, width Высота и ширина.
focus Был ли в момент события фокус у окна?