Назначение функции событию виджета называется привязкой события. Назначенная функция вызывается автоматически при возникновении события.
Знакомство с привязкой событий Tkinter
Ранее вы узнали, как привязать функцию к событию виджета с помощью опции command. Однако важно отметить, что не все виджеты Tkinter поддерживают опцию command.
Таким образом, Tkinter предоставляет альтернативный способ привязки событий к функциям в Python через метод bind().
Ниже показан общий синтаксис метода bind():
widget.bind(event, handler, add=None)
Когда в виджете происходит событие, Tkinter автоматически вызывает обработчик с подробностями события.
Если вы хотите зарегистрировать дополнительный обработчик, вы можете передать ‘+’ аргументу add. Это позволяет иметь несколько обработчиков событий, реагирующих на одно и то же событие.
Примеры привязки событий Tkinter
Следующая программа иллюстрирует, как привязать функцию return_pressed к событию нажатия клавиши Return кнопки «Сохранить»:
import tkinter as tk
from tkinter import ttk
def return_pressed(event):
print('Return key pressed.')
root = tk.Tk()
btn = ttk.Button(root, text="Save")
btn.bind('<Return>', return_pressed)
btn.focus()
btn.pack(expand=True)
root.mainloop()
В этом примере следующий оператор вызывает метод bind() виджета кнопки для привязки события нажатия клавиши Return:
btn.bind('<Return>', return_pressed)
В следующем примере показано, как использовать метод bind() для регистрации нескольких обработчиков для одного и того же события:
import tkinter as tk
from tkinter import ttk
def return_pressed(event):
print('Return key pressed.')
def log(event):
print(event)
root = tk.Tk()
btn = ttk.Button(root, text="Save")
btn.bind('<Return>', return_pressed)
btn.bind('<Return>', log, add='+')
btn.focus()
btn.pack(expand=True)
root.mainloop()
Когда вы перемещаете фокус на кнопку и нажимаете клавишу Return, Tkinter автоматически вызывает функции return_pressed и log.
Следующий код привязывает функцию log() к событию нажатия клавиши Return кнопки «Сохранить»:
btn.bind('<Return>', log, add='+')
В этом операторе третий аргумент add=’+’ регистрирует дополнительный обработчик, которым является функция log().
Если аргумент add=’+’ не указан, метод bind() заменит существующий обработчик(return_pressed) новым(log).
Модели событий
Tkinter использует шаблоны событий для сопоставления имен событий с обработчиками. Например, обозначает нажатие клавиши Return.
Ниже показан общий синтаксис шаблона событий:
<modifier-type-detail>
В этом синтаксисе событие заключено в угловые скобки(). Внутри угловых скобок находится ноль или более модификаторов, тип события и подробная информация о событии.
Например, обозначает нажатие клавиши A на клавиатуре, а представляет нажатие клавиш Alt + Ctrl + Delete.
В следующем разделе показаны наиболее часто используемые модификаторы событий, типы событий и подробности событий.
1) Модификаторы событий
В следующей таблице перечислены наиболее часто используемые модификаторы событий:
| Модификатор события | Значение |
|---|---|
| Alt | Клавиша Alt удерживается |
| Control | Клавиша Ctrl удерживается |
| Shift | Клавиша Shift удерживается |
| Any | Этот модификатор делает тип события общим. Например, шаблон события применяется к нажатию любой клавиши. |
Типы событий
В следующей таблице показаны наиболее часто используемые типы событий:
| Тип | Имя | Описание |
|---|---|---|
| 36 | Activate | Состояние виджета меняется с неактивного на активное. |
| 4 | Button | Нажата одна кнопка мыши. |
| 5 | ButtonRelease | Одна кнопка мыши отпущена. |
| 22 | Configure | Размер виджета изменен. |
| 37 | Deactivate | Состояние виджета меняется с активного на неактивное. |
| 17 | Destroy | Виджет уничтожается. |
| 7 | Enter | Указатель мыши перемещается в видимую часть виджета. |
| 12 | Expose | Некоторая часть виджета или приложения видна после того, как была закрыта другим окном. |
| 9 | FocusIn | Фокус ввода был перенесен в виджет. |
| 10 | FocusOut | Фокус ввода был перемещен за пределы виджета. |
| 2 | KeyPress | Нажата клавиша. |
| 3 | KeyRelease | Ключ отпущен. |
| 8 | Leave | Указатель мыши выведен за пределы виджета. |
| 19 | Map | Виджет помещается в контейнер, например, путем вызова метода pack() или grid(). |
| 6 | Motion | Указатель мыши перемещается полностью в пределах виджета. |
| 38 | MouseWheel | Пользователь вращал колесико мыши вверх или вниз. |
| 18 | Unmap | Виджет отменяет отображение и больше не отображается, например, при вызове метода grid_remove() для виджета. |
| 15 | Visibility | По крайней мере, какая-то часть окна приложения становится видна на экране. |
Подробности события
В следующей таблице показано несколько способов именования ключей:
| .keysym | .код ключа | .keysym_num | Ключ |
|---|---|---|---|
| Alt_L | 64 | 65513 | Левая клавиша alt |
| Alt_R | 113 | 65514 | Правая клавиша alt |
| BackSpace | 22 | 65288 | Возврат на одну позицию |
| Cancel | 110 | 65387 | Пробел |
| Caps_Lock | 66 | 65549 | CapsLock |
| Control_L | 37 | 65507 | Левая клавиша управления |
| Control_R | 109 | 65508 | Правая клавиша управления |
| Delete | 107 | 65535 | Delete |
| Down | 104 | 65364 | ↓ |
| End | 103 | 65367 | end |
| Escape | 9 | 65307 | esc |
| Execute | 111 | 65378 | SysReq |
| F1 | 67 | 65470 | Функциональная клавиша F1 |
| F2 | 68 | 65471 | Функциональная клавиша F2 |
| Fi | 66+я | 65469+i | Функциональная клавиша Fi |
| F12 | 96 | 65481 | Функциональная клавиша F12 |
| Home | 97 | 65360 | home |
| Insert | 106 | 65379 | insert |
| Left | 100 | 65361 | ← |
| Linefeed | 54 | 106 | Linefeed (control-J) |
| KP_0 | 90 | 65438 | 0 на клавиатуре |
| KP_1 | 87 | 65436 | 1 на клавиатуре |
| KP_2 | 88 | 65433 | 2 на клавиатуре |
| KP_3 | 89 | 65435 | 3 на клавиатуре |
| KP_4 | 83 | 65430 | 4 на клавиатуре |
| KP_5 | 84 | 65437 | 5 на клавиатуре |
| KP_6 | 85 | 65432 | 6 на клавиатуре |
| KP_7 | 79 | 65429 | 7 на клавиатуре |
| KP_8 | 80 | 65431 | 8 на клавиатуре |
| KP_9 | 81 | 65434 | 9 на клавиатуре |
| KP_Add | 86 | 65451 | + на клавиатуре |
| KP_Begin | 84 | 65437 | Центральная клавиша(та же, что и клавиша 5) на клавиатуре |
| KP_Decimal | 91 | 65439 | Десятичная дробь(.) на клавиатуре |
| KP_Delete | 91 | 65439 | delete на клавиатуре |
| KP_Divide | 112 | 65455 | / на клавиатуре |
| KP_Down | 88 | 65433 | ↓ на клавиатуре |
| KP_End | 87 | 65436 | end на клавиатуре |
| KP_Enter | 108 | 65421 | enter на клавиатуре |
| KP_Home | 79 | 65429 | home на клавиатуре |
| KP_Insert | 90 | 65438 | insert на клавиатуру |
| KP_Left | 83 | 65430 | ← на клавиатуре |
| KP_Multiply | 63 | 65450 | × на клавиатуре |
| KP_Next | 89 | 65435 | PageDown на клавиатуре |
| KP_Prior | 81 | 65434 | PageUp на клавиатуре |
| KP_Right | 85 | 65432 | → на клавиатуре |
| KP_Subtract | 82 | 65453 | — на клавиатуре |
| KP_Up | 80 | 65431 | ↑ на клавиатуре |
| Next | 105 | 65366 | PageDown |
| Num_Lock | 77 | 65407 | NumLock |
| Pause | 110 | 65299 | pause |
| 111 | 65377 | PrintScrn | |
| Prior | 99 | 65365 | PageUp |
| Return | 36 | 65293 | Клавиша Enter |
| Right | 102 | 65363 | → |
| Scroll_Lock | 78 | 65300 | ScrollLock |
| Shift_L | 50 | 65505 | Левая клавиша Shift |
| Shift_R | 62 | 65506 | Правая клавиша Shift |
| Tab | 23 | 65289 | Клавиша табуляции |
Привязка событий к корневому окну
Вы узнали, как привязать событие к определенному виджету. Tkinter также позволяет привязать событие к окну верхнего уровня.
В этом случае синтаксис для bind() тот же самый, за исключением того, что вы можете вызвать его в корневом окне следующим образом:
root.bind('<Return>', handler)
Уровни связывания
В предыдущем примере вы узнали, как привязать событие к определенному экземпляру виджета. Это называется привязкой на уровне экземпляра.
Tkinter также позволяет вам привязывать событие ко всем экземплярам виджета. Например, вы можете привязать событие ко всем текстовым полям в программе:
root.bind_class('Entry', '<Control-V>', paste)
Кстати, для создания текстового поля в Tkinter используется виджет Entry.
Это называется привязкой на уровне класса, поскольку вы привязываете событие к классу, а не к экземпляру.
Освобождение от обязательных событий
Иногда вам может понадобиться отменить эффект более ранней привязки. Для этого можно использовать метод unbind():
widget.unbind(event)
В следующем примере отменяется привязка события к кнопке btn:
btn.unbind('<Return>') 