Tkinter


Události

Binds Aplikace Tkinteru běží většinu svého času uvnitř "smyčky události" zavedené metodou mainloop().
Tato smyčka čeká na výskyt události, jíž může být například stisk tlačítka klávesnice nebo myši - viz samostatný odstavec.

Událost se přihodí widgetu nebo celé aplikaci. Odezvu na událost zajišťuje její spojení s určenou funkcí.

Callback

U widgetů Button, Checkbutton, Radiobutton, Scale a Spinbox lze tuto funkci připojit jako hodnotu parametru command (command="callback").
Callback může být buď nativní nebo uživatelsky definovaná funkce (která nepříjímá žádné argumenty), metoda, výraz lambda či prostý argument.

Připojení funkce

Následující skript vytvoří okno s jedním tlačítkem, jemuž jsou podřízeny dvě funkce - vlastní a nativní:
    Prostý klik se projeví zápisem do konzoly.
    Dvojklik zavře aplikaci.
Ukázka je zajímavá také tím, že nedeklaruje nejvyšší okno - zkuste si jej do skriptu doplnit - root = Tk():
from tkinter import *

def hello(event):
    print("Single Click, Button-l") 
def quit(event):                           
    print("Double Click, so let's stop") 
    import sys; sys.exit() 

widget = Button(None, text='Mouse Clicks')
widget.pack()
widget.bind('<Button-1>', hello)
widget.bind('<Double-1>', quit) 
widget.mainloop()

Připojení metody

from tkinter import*

from tkinter import*

class Program:
    def __init__(self):
        b = Button(root, text="Klikni si",
                    command=self.callback).pack()
    def callback(self):
        print("Kliknuto!")

root = Tk()
program = Program()
root.mainloop()

Připojení argumentů funkcí lambda

Skutečnost, že callback je funkce bez argumentů, může být nepříjemné, chceme-li toto připojení použít pro více widgetů Button.
from tkinter import *

def callback(number):
    print("Button", number) 

Button(text='One', command=lambda: callback(1)).pack()
Button(text='Two', command=lambda: callback(2)).pack()
Button(text='Three', command=lambda: callback(3)).pack()

mainloop()

Metoda .bind

Většinu událostí lze s potřebnými funkcemi spojit metodou bind:
    widget.bind(event, handler); handler je název volané funkce.

Metodu .bind lze uplatnit
  1. pro jediný widget - instance binding, například:
        self.canv.bind("<Button-2>", drawKruh)
  2. pro všechny widgety jedné třídy - class binding, například:
        self.bind_class("Canvas", "<Button-2>", self.drawKruh)
  3. pro celou aplikaci - application binding, například :
        self.bind_all("<Key-Print>", self.printScreen)


V dalším jednoduchém příkladě si ukážeme použití události "motion" (pohyb), k níž dojde, pohybujeme-li po widgetu myší:
from tkinter import *

def motion(event):
    print("Mouse position: (%s %s)" % (event.x, event.y))
    return

master = Tk()
whatever_you_do = "Whatever you do will be insignificant,
		   but it is very important 
	           that you do it.\n(Mahatma Gandhi)"
msg = Message(master, text = whatever_you_do)
msg.config(bg='lightgreen', font=('times', 24, 'italic'))
msg.bind('<Motion>',motion)
msg.pack()
mainloop()

Při každém pohybu ukazatele po widgetu Message se vytiskne jeho pozice.

Popis události

Pro podrobný popis události používá Tkinter tak zvaný zadávací formát (event sequence), který se obecně skládá ze tří částí:
<[Modifikátor-]...typ[-detail]>
Pole "typ" je základní částí formátu, zatímco pole "modifikátor" a "detail" jsou nepovinné a často se vynechávají. Poskytují dodatečnou informaci pro vybraný typ události.
V poli "modifikátor" se používají výrazy Alt, Any, Control, Double, Lock, Shift a Triple.
V poli "detail" se uvádí upřesnění k typu události, jako je např. číselný kód klávesy.
Dvojklik levé klávesy myši se jako událost vyjádří sekvencí<Double-Button-1>
V poli "typ" se uvádí název události tak, jak je uveden v následujícím přehledu:

Typ Název typu Popis
2
3
<KeyPress>
<KeyRelease>
Uživatel stiskl či uvolnil libovolnou klávesu klávesnice. Specifikace klávesy je vyjádřena v detailní části - Key names.
4<Button> nebo
<ButtonPress>
Klávesa myši je stisknuta s ukazatelem nad widgetem. O kterou klávesu se jedná, určuje detailní část sekvence, například levá klávesa je definována výrazem <Button-1>, střední klávesa výrazem <Button-2> a pravá klávesa výrazem <Button-3>.
Výraz <Button-4> definuje rolování kolečka střední klávesy nahoru a <Button-5> dolů.
Místo <Button-1> lze použít <ButtonPress-1> nebo <1>; jsou to prakticky synonyma.
5<ButtonRelease> Událostí je uvolnění stisknuté myší klávesy. Pro určení levé, střední a pravé klávesy použijeme výraz <ButtonRelease-1>, <ButtonRelease-2> a <ButtonRelease-3>. Aktuální pozice myšího ukazatele udávají atributy objektu události (event.x, event.y).
6<Motion> Ukazatel myši je přemisťován stlačenou klávesou. Pro určení levé, střední či pravé klávesy použijeme výraz <B1-Motion>, <B2-Motion> and <B3-Motion>. Aktuální pozice myšího ukazatele udávají atributy objektu události (event.x, event.y).
7<Enter> Ukazovátko myši vstoupilo do pole widgetu.
Attention: To neznamená, že uživatel stiskl klávesu "Enter"; pro tento případ se používá výraz <Return>.
8<Leave> Ukazovátko opustilo widget.
9<FocusIn> Zaměření (focus) klávesnice bylo přesunuto k widgetu nebo k jeho potomkovi.
10<FocusOut> Zaměření klávesnice bylo přesunuto k jinému widgetu.
12<Expose> Tato událost vznikne, odhalí-li se aspoň část widgetu nebo aplikace dosud zakrytá jiným oknem.
17<Destroy> Tato událost vznikne likvidací widgetu.
19<Map> Widget byl zviditelněn neboli exponován (metodou pack, grid či place).
22<Configure> Změna velikosti widgetu. Nová velikost je dána atributy "width" a "height" objektu události, jejichž hodnoty se přenesou do volané procedury. Na některých platformách to může znamenat změnu pozice.
36<Activate> Stav widgetu se mění z neaktivního v aktivní.
37<Deactivate> Stav widgetu se mění z aktivního v neaktivní.
38<MouseWheel> Uživatel otočil kolečkem myši nahoru nebo dolů (nechodí v Linuxu).
Další možnosti
<Return> Uživatel stiskl klávesu Enter. Stejně jako tuto klávesu lze připojit všechny klávesy klávesnice. Specielními klávesami jsou: Cancel (the Break key), BackSpace, Tab, Return(the Enter key), Shift_L (any Shift key), Control_L (any Control key), Alt_L (any Alt key), Pause, Caps_Lock, Escape, Prior (Page Up), Next (Page Down), End, Home, Left, Up, Right, Down, Print, Insert, Delete, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, Num_Lock a Scroll_Lock.
a Uživatel stiskl klávesu "a". Většina tisknutelných znaků může být takto použita. Výjimkou jsou mezerník (<space>) a znak "méně než" (<less>). Pamatujte, že 1 je vazba pro klávesnici, zatímco <1> je vazba pro klávesu myši.
<Shift-Up> Uživatel stiskl šipku nahoru se stisknutou klávesou Shift. Lze použít předpony Alt, Shift a Control.


Zaměření widgetu - focus

Zaměření neboli focus je dvoupólový stav widgetu, který může být deklarovanou událostí <FocusIn>, <FocusOut>.

Řekneme-li, že je widget zaměřen (má focus), znamená to, že k tomuto widgetu je aktuálně směrován vstup z klávesnice.

O tom, zda může být widget zaměřen, rozhoduje hodnota jeho parametru takefocus (= 0 nebo 1). Widgety Frame, Label a Menu mají tuto hodnotu implicitně nastavenou na nulu.

Podrobnější informace viz NMT 53. Focus