===== bind =====
Метод **bind** привязывает событие к какому-либо действию (нажатие кнопки мыши, нажатие клавиши на клавиатуре и т.д.). bind принимает три аргумента:
* название события
* функцию, которая будет вызвана при наступлении события
* третий аргумент (необязательный) - строка "+" - означает, что эта привязка добавляется к уже существующим. Если третий аргумент опущен или равен пустой строке - привязка замещает все другие привязки данного события к виджету.
Метод **bind** возвращает идентификатор привязки, который может быть использован в функции **unbind**.
Обратите внимание, что если **bind** привязан к окну верхнего уровня, то Tkinter будет обрабатывать события всех виджетов этого окна (см. также bind_all ниже).
Функция, которая вызывается при наступлении события, должна принимать один аргумент. Это объект класса Event, в котором описано наступившее событие. Объект класса Event имеет следующие атрибуты (в скобках указаны события, для которых этот атрибут установлен):
* **serial** - серийный номер события (все события)
* **num** - номер кнопки мыши (ButtonPress, ButtonRelease)
* **focus** - имеет ли окно фокус (Enter, Leave)
* **height и width** - ширина и высота окна (Configure, Expose)
* **keycode** - код нажатой клавиши (KeyPress, KeyRelease)
* **state** - состояние события (для ButtonPress, ButtonRelease, Enter, KeyPress, КeyRelease, Leave, Motion - в виде числа; для Visibility - в виде строки)
* **time** - время наступления события (все события)
* **x и y** - координаты мыши
* **x_root и y_root** - координаты мыши на экране (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
* **char** - набранный на клавиатуре символ (KeyPress, KeyRelease)
* **send_event** - см. документацию по X/Windows
* **keysym** - набранный на клавиатуре символ (KeyPress, KeyRelease)
* **keysym_num** - набранный на клавиатуре символ в виде числа (KeyPress, KeyRelease)
* **type** - тип события в виде числа (все события)
* **widget** - виджет, который получил событие (все события)
* **delta** - изменение при вращении колеса мыши (MouseWheel)
Эта функция может возвращать строки "continue" и "break". Если функция возвращает "continue" то Tkinter продолжит обработку других привязок этого события, если "break" - обработка этого события прекращается. Если функция ничего не возвращает (если возвращает None), то обработка событий продолжается (т.е. это эквивалентно возвращению "continue").
==== Названия событий ====
Есть три формы названия событий. Самый простой случай это символ ASCII. Так описываются события нажатия клавиш на клавиатуре:
widget.bind("z", callback)
callback вызывается каждый раз, когда будет нажата клавиша "z".
----
Второй способ длиннее, но позволяет описать больше событий. Он имеет следующий синтаксис:
Название события заключено в угловые скобки. Внутри имеются ноль или более модификаторов, тип события и дополнительная информация (номер нажатой клавиши мыши или символ клавиатуры) Поля разделяются дефисом или пробелом. Пример (привязываем одновременное нажатие Ctrl+Shift+q):
widget.bind("", callback)
(в данном примере KeyPress можно убрать).
----
Третий способ позволяет привязывать виртуальные события - события, которые генерируются самим приложением. Такие события можно создавать самим, а потом привязывать их. Имена таких событий помещаются в двойные угловые скобки: <>. Есть некоторое количество уже определённых виртуальных событий.
==== Список модификаторов ====
* **Return** - Enter
* **Escape** - Esc
* **Control** - Ctrl
* **Alt**
* **Shift**
* **Lock**
* **Extended**
* **Prior** - PgUp
* **Next** - PgDown
* **Button1, B1** - нажата первая (левая) кнопка мыши
* **Button2, B2** - вторая (средняя) кнопка мыши
* **Button3, B3** - третья (правая)
* **Button4, B4** - четвёртая
* **Button5, B5** - пятая
* **Mod1, M1, Command**
* **Mod2, M2, Option**
* **Mod3, M3**
* **Mod4, M4**
* **Mod5, M5**
* **Meta, M**
* **Double** - двойной щелчок мыши (например, )
* **Triple** - тройной
* **Quadruple** - четверной
====Типы событий====
Здесь перечислены все возможные типы событий, для самых часто используемых дано описание. Более подробно см. [[http://www.tcl.tk/man/tcl8.5/TkCmd/bind.htm#M7|man bind]].
* **Activate, Deactivate**
* **MouseWheel** - прокрутка колесом мыши
* **KeyPress, KeyRelease** - нажатие и отпускание клавиши на клавиатуре
* **ButtonPress, ButtonRelease, Motion** - нажатие, отпускание клавиши мыши, движение мышью
* **Configure** - изменение положения или размера окна
* **Map, Unmap** - показывание или сокрытие окна (например, в случае сворачивания/разворачивания окна пользователем)
* **Visibility**
* **Expose** - событие генерируется, когда необходимо всё окно или его часть перерисовать
* **Destroy** - закрытие окна
* **FocusIn, FocusOut** - получение или лишение фокуса
* **Enter, Leave** - Enter генерируется когда курсор мыши "входит" в окно, Leave - когда "уходит" из окна
* **Property**
* **Colormap**
* **MapRequest, CirculateRequest, ResizeRequest, ConfigureRequest, Create**
* **Gravity, Reparent, Circulate**
====Клавиатурные символы====
Полный список см. [[http://www.tcl.tk/man/tcl8.5/TkCmd/keysyms.htm|man keysyms]].
====Примеры====
или <1> - нажата левая клавиша мыши. \\
- движение мышью с нажатой на клавиатуре клавишей Alt. \\
- нажатие любой клавиши на клавиатуре. \\
from Tkinter import *
root=Tk()
def leftclick(event):
print u'Вы нажали левую кнопку мыши'
def rightclick(event):
print u'Вы нажали правую кнопку мыши'
button1=Button(root, text=u'Нажми')
button1.pack()
button1.bind('', leftclick)
button1.bind('', rightclick)
root.mainloop()
====Дополнительные методы====
* **bind_all** - создаёт привязку для всех виджетов приложения. Отличие от привязки к окну верхнего уровня заключается в том, что в случае привязки к окну привязываются все виджеты этого окна, а этот метод привязывает все виджеты приложения (у приложения может быть несколько окон).
* **bind_class** - создаёт привязку для всех виджетов данного класса
from Tkinter import *
def callback(e):
print u'Нажата кнопка', e.widget['text']
root=Tk()
button1 = Button(root, text='1')
button1.pack()
button2 = Button(root, text='2')
button2.pack()
root.bind_class('Button', '<1>', callback)
root.mainloop()
* **bindtags** - позволяет изменить порядок обработки привязок. По умолчанию порядок следующий: виджет, класс, окно, all; где виджет - привязка к виджету (bind), класс - привязка к классу (bind_class), окно - привязка к окну (root.bind), all - привязка всех виджетов (bind_all).
Пример, меняем порядок обработки привязок на обратный:
from Tkinter import *
def callback1(e): print 'callback1'
def callback2(e): print 'callback2'
def callback3(e): print 'callback3'
def callback4(e): print 'callback4'
root=Tk()
button = Button(root)
button.pack()
button.bind('<1>', callback1)
root.bind_class('Button', '<1>', callback2)
root.bind('<1>', callback3)
root.bind_all('<1>', callback4)
button.bindtags(('all', root, 'Button', button))
root.mainloop()
* **unbind** - отвязать виджет от события. В качестве аргумента принимает идентификатор, полученный от метода bind.
* **unbind_all** - то же, что и unbind, только для метода bind_all.
* **unbind_class** - то же, что и unbind, только для метода bind_class.
====Пример программы радуга====
from tkinter import *
from tkinter import messagebox
colors = {
'Красный':'#ff0000',
'Оранжевый':'#ff7d00',
'Желтый':'#ffff00',
'Зеленый':'#00ff00',
'Голубой':'#007dff',
'Синий':'#0000ff',
'Фиолетовый':'#7d00ff'
}
def callback(event, color, code):
e.focus()
if event.keycode == 13:
if e.get() == "Белый":
colors["Белый"] = "#FFFFFF"
e['bg'] = colors[e.get()]
else:
print(event)
e.delete(0, END)
e.insert(0, color)
root=Tk()
root.geometry("400x300")
e = Entry(root, justify=CENTER, font="Arial 15")
e.pack(fill=X, expand=1, padx=10, pady=10)
e.bind("", lambda event, color="Белый", code="#FFFFFF": callback(event, color, code))
e.bind("", lambda event, color="Белый", code="#FFFFFF": callback(event, color, code))
for color, code in colors.items():
b = Button(root, bg=code)
b.pack(fill=X)
b.bind("", lambda event, color=color, code=code: callback(event, color, code))
b.bind("", lambda event, color="Белый", code="#FFFFFF": callback(event, color, code))
root.mainloop()
{{ :python:оконное_приложение:tkinter:event1.png?200 |}}