Опубликован: 22.12.2005 | Уровень: для всех | Доступ: платный
Лекция 12:

Создание приложений с графическим интерфейсом пользователя

Основы 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 Был ли в момент события фокус у окна?
  • keycode Код символа (скан-код клавиатуры).
  • keysym Символическое имя клавиши.
  • serial Серийный номер события. Увеличивается по мере возникновения событий.
  • time Время возникновения события. Все время увеличивается.
  • widget Виджет, в котором возникло событие.
  • x, y Координаты указателя в виджете во время события.
  • x_root, y_root Координаты указателя на экране во время события.

В принципе, совсем необязательно, чтобы события обрабатывал тот же виджет, который их первично принял. Например, можно перенаправить все события внутри подчиненных виджетов на данный виджет с помощью метода grab_set() ( grab_release() освобождает виджет от этой обязанности). В Tk существуют и другие возможности управления событиями, которые можно изучить по документации.

Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?

 

Павел Ялганов
Павел Ялганов

Скажите экзамен тоже будет ввиде теста? или там будет какое то практическое интересное задание?

Максим Чиндясов
Максим Чиндясов
Россия, Нижний Новгород
Ольга Коваль
Ольга Коваль
Беларусь, Минск