Гузариш ба мундариҷа
Мавзӯи 5 аз 6

Рӯйдодҳо

Рӯйдодҳо барои чӣ лозиманд

Тугма бо command танҳо як амалро фаро мегирад. Ба муҳаррир миёнабурҳои клавиатура, ба майдон вокуниш ба Enter ва ба холст ҳаракати муш лозиманд. Рӯйдод воқеаи рухдодаро тавсиф карда, маълумоти вобастаро медиҳад: координатаҳо, тугма ва ҳолати тағйирдиҳандаҳо.

Барнома клавиатураро дар даври беохир намепурсад. Он коркардкунандаҳоро сабт карда, идоракуниро ба mainloop() бармегардонад. Мисолҳои зер мустақиланд; рӯйдодҳои сунъӣ вокунишро бе вуруди дастӣ месанҷанд. Дар мисолҳое, ки равзанаи воқеӣ истифода мешавад, он худкор баста мешавад.

1. bind рӯйдодро ба функсия мепайвандад

widget.bind(pattern, handler) коркардкунандаро сабт мекунад. Қолаб сатре дар қавсҳои кунҷӣ аст, масалан <Button-1> барои тугмаи чапи муш. Tkinter ба функсия як объекти event медиҳад. event.x ва event.y ҷойи нишондиҳандаро нисбат ба виджети қабулкунандаи рӯйдод медиҳанд, на нисбат ба тамоми экран.

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, width=120, height=80)
canvas.pack()

def on_click(event):
    print(event.x, event.y)

canvas.bind("<Button-1>", on_click)
root.after(100, lambda: canvas.event_generate("<Button-1>", x=18, y=27))
root.after(200, root.destroy)
root.mainloop()

Барориш:

18 27

Рӯйдод пас аз намоён шудани равзана фиристода мешавад: виджети ҳанӯз намоённашуда метавонад пахши сунъиро коркард накунад. Дар барнома ин амалро корбар иҷро мекунад. command-и тугма функсияро бе аргумент даъват мекунад, аммо bind ҳамеша объекти рӯйдодро медиҳад.

2. Кадом рӯйдодро интихоб кунем

Қолаб Маъно
<ButtonPress-1> ё <Button-1> Пахши тугмаи чап
<ButtonRelease-1> Раҳо кардани тугмаи чап
<B1-Motion> Ҳаракат бо тугмаи чапи пахшшуда
<Motion> Ҳаракати нишондиҳанда
<Double-Button-1> Пахши дукарата
<Key> Пахши тугмаи клавиатура
<Return>, <Escape>, <Left> Тугмаи муайян
<Control-s> Миёнабури Ctrl+S

Вуруди клавиатура одатан ба виджети дорои фокус меравад. Масалан, entry.focus_set() фокусро барои майдон дархост мекунад. Ҳангоми пайваст кардан ба равзанаи асосӣ қоидаҳои паҳншавии рӯйдодҳо аз виджетҳои фарзанди он ҳам амал мекунанд.

3. keysym ва char ба саволҳои гуногун ҷавоб медиҳанд

keysym номи тугма аст: plus, Return, BackSpace, KP_2. char аломати воридшуда аст: +, 2; барои баъзе тугмаҳои хизматӣ он сатри холӣ ё аломати идоракунӣ мешавад. Ном барои фармонҳо ва аломат барои матн қулай аст. Барои такроршавии натиҷа мисоли навбатӣ маълумоти рӯйдодро бо SimpleNamespace месозад: ин объекти одӣ бо майдонҳои номдор аст.

from types import SimpleNamespace

for keysym, char in (("plus", "+"), ("KP_2", "2"), ("Shift_L", "")):
    event = SimpleNamespace(keysym=keysym, char=char)
    print(event.keysym, repr(event.char))

Барориш:

plus '+'
KP_2 '2'
Shift_L ''

Ҳар char-и ғайрихолиро аломати чопшаванда нашуморед: BackSpace метавонад "\b" дошта бошад. Коркардкунанда аввал фармонҳои хизматиро мешиносад, баъд аломатҳои иҷозатшударо месанҷад. Қоидаҳои дақиқи ҳисобкунак дар машқ мемонанд.

4. Тағйирдиҳандаҳо маҷмӯи битҳоянд

event.state ададест, ки битҳои алоҳидааш Shift, Control ва ҳолатҳои дигарро ифода мекунанд. Бит парчамест бо ҳолати «фаъол» ё «ғайрифаъол». & мавҷудияти парчами муайянро новобаста аз ҳамсояҳо месанҷад. Дар модели Windows-и масъалаҳо Shift ба 1, CapsLock ба 2, Control ба 4, NumLock ба 8 ва Alt ба 0x20000 баробар аст. Дар платформаҳои дигар қиматҳо фарқ карда метавонанд.

CONTROL = 4
for state in (4, 12, 0):
    print(state, state == CONTROL, bool(state & CONTROL))

Барориш:

4 True True
12 False True
0 False False

5. Чанд коркардкунанда ва қатъи рӯйдод

Даъвати такрории bind() барои як қолаб одатан пайвасти пешинаро иваз мекунад. Параметри add="+" коркардкунандаро илова мекунад. Баргардондани сатри "break" коркарди минбаъдаи ҳамон рӯйдодро дар занҷири пайвастҳо қатъ мекунад. Ин вақте қулай аст, ки амал иҷро шудааст ва рафтори стандартӣ дигар лозим нест.

import tkinter as tk

root = tk.Tk()
root.withdraw()

def first(event):
    print("Якум")
    return "break"

def second(event):
    print("Дуюм")

root.bind("<<Demo>>", first)
root.bind("<<Demo>>", second, add="+")
root.update_idletasks()
root.event_generate("<<Demo>>")
root.destroy()

Барориш:

Якум

<<Demo>> рӯйдоди маҷозӣ бо номи интихобкардаи мост. Он барои санҷидани занҷири коркардкунандаҳо қулай аст; рӯйдодҳои воқеии муш қавсҳои кунҷии яктоӣ доранд.

6. Маълумот барои кашолакунӣ

Кашолакунӣ оғоз, ҳаракат ва анҷом дорад. Ҳангоми пахш объекти интихобшуда ва нуқтаи нишондиҳандаро нигоҳ медоранд. Ҳангоми ҳаракат фарқи нуқтаи наву пешина муҳим аст: ин ҷойивазкунӣ аст, на ҷойи мутлақи кунҷи шакл. Ҳангоми раҳо кардан интихобро тоза мекунанд. Canvas объектро бо move() мекӯчонад ва бо tag_raise() боло мебардорад; навсозии муфассали ҳолатро дар масъала амалӣ кардан лозим аст.

from types import SimpleNamespace

last = (30, 40)
event = SimpleNamespace(x=37, y=36)
dx, dy = event.x - last[0], event.y - last[1]
print(dx, dy)
last = (event.x, event.y)
print(last)

Барориш:

7 -4
(37, 36)

Дар дохил чӣ рӯй медиҳад

Система рӯйдодро ба навбати Tk илова мекунад. Давр пайвастҳои мувофиқро барои виджет, синфи он ва равзана интихоб карда, объекти event месозад ва функсияи Python-ро даъват мекунад. Пас аз анҷоми он коркарди навбат идома меёбад. Ҳолати кашолакунӣ байни даъватҳо нигоҳ дошта мешавад; коркардкунанда дар дохили худ ҳаракати навбатиро интизор намешавад.

Хатоҳои маъмул ва ислоҳи онҳо

  1. def on_click(): ... бо bind аргументи ғайричашмдошт гирифта, ба TypeError меорад. Параметри event илова кунед.
  2. event.state == 4 ҳангоми NumLock дигар Ctrl-ро намебинад. Битро санҷед: bool(event.state & 4).
  3. keysym == "+" тугмаи бо номи plus-ро намешиносад. Барои вуруди аломат char ва барои фармон keysym-и мувофиқро гиред.
  4. bind("<Key>", f)-и дуюм коркардкунандаи пешинаи ин қолабро иваз мекунад. Барои илова add="+" лозим аст.
  5. Гузарондани кунҷи шакл ба event.x, event.y ҳангоми гирифтан ҷаҳиш медиҳад. Нуқтаи пешинаро нигоҳ дошта, фарқи координатаҳоро истифода баред.

Ёднома

  • Пайваст: widget.bind("<...>", handler); имзои функсия: handler(event).
  • Муш: x, y; клавиатура: keysym, char; тағйирдиҳандаҳо: state & MASK.
  • Фокус: focus_set(); занҷир: add="+"; қатъ: return "break".
  • Кашолакунӣ: пахш → ҳаракат бо ҷойивазкунӣ → раҳо кардан.
  • Коркардкунанда зуд анҷом ёфта, идоракуниро ба давр бармегардонад.