Холст, таймерҳо ва ҳисобкунак
Холст ва таймерро барои чӣ якҷо мекунем
Label-и одӣ матни тайёрро нишон медиҳад. Барои нақша, тӯбчаи ҳаракаткунанда ё майдони бозӣ холст — Canvas лозим аст: барнома дар он объектҳои графикиро месозад ва тағйир медиҳад. Барои тадриҷан рӯй додани тағйирот таймери after()-ро истифода мебаранд.
Дар ин мавзӯъ се вазифаи мустақил вомехӯранд: нишон додани вақт, нав кардани ҳаракат ва пайвастани тугмаҳои ҳисобкунак ба мантиқи ҳисоб. Холст барои тасвир, соат барои чен кардани вақт ва функсияҳо барои ҳисоб масъуланд. Ин ҷудокунӣ санҷидани ҳар қисмро осон мекунад. Ҳамаи мисолҳо мустақиланд ва равзанаҳоро худкор мебанданд.
1. Координатаҳо ва рақами шакл
Ибтидои координатаҳои холст дар кунҷи чапи боло аст. Меҳвари x ба рост ва y ба поён равона аст. Росткунҷаро бо ду кунҷи муқобил медиҳанд. create_oval() эллипсро дар ҳамон гуна росткунҷаи маҳдудкунанда ҷой медиҳад; агар тарафҳо баробар бошанд, доира ҳосил мешавад. Методи сохтан шиносаи объект бармегардонад, ки барои тағйироти минбаъда лозим аст.
import tkinter as tk
root = tk.Tk()
root.withdraw()
canvas = tk.Canvas(root, width=240, height=160, bg="black")
canvas.pack()
ball = canvas.create_oval(10, 20, 30, 40, fill="yellow")
canvas.create_line(0, 0, 100, 80, fill="white", width=2)
print(canvas.type(ball))
print(canvas.coords(ball))
root.destroy()
Барориш:
oval
[10.0, 20.0, 30.0, 40.0]
2. Ба ҷойи сохтани нав объекти мавҷударо тағйир диҳед
move(item, dx, dy) ба координатаҳо ҷойивазкунӣ илова мекунад, coords(item, ...) бошад, онҳоро аз нав медиҳад. Ин ду амали гуногунанд. itemconfig() хосиятҳои шаклро тағйир медиҳад ва delete() онро нест мекунад. Хосиятҳои тамоми холстро canvas.config() ва объекти алоҳидаро canvas.itemconfig() тағйир медиҳад.
import tkinter as tk
root = tk.Tk()
root.withdraw()
canvas = tk.Canvas(root)
canvas.pack()
box = canvas.create_rectangle(10, 10, 40, 30, fill="green")
canvas.move(box, 5, -2)
canvas.itemconfig(box, fill="red")
print(canvas.coords(box))
print(canvas.itemcget(box, "fill"))
canvas.delete(box)
print(len(canvas.find_all()))
root.destroy()
Барориш:
[15.0, 8.0, 45.0, 28.0]
red
0
Бо create_text() матн ҳам сохта, баъд параметри text-и онро нав кардан мумкин аст. Ҳар кадр болои матни кӯҳна матни нав насозед: рӯйхати объектҳо калон мешавад, ҳарчанд ба назар як навишта менамояд.
3. after як даъватро таъйин мекунад
after(ms, f) кори мавқуфро ба даври рӯйдодҳо илова карда, фавран шиносаи таймерро бармегардонад. Функсия пеш аз таъхири дода иҷро намешавад, вале агар давр банд бошад, дертар иҷро шуда метавонад. Барои такрор коркардкунанда худро боз таъйин мекунад. Дар дохили он на sleep() ва на даври беохир лозим аст.
import tkinter as tk
root = tk.Tk()
root.withdraw()
count = 0
def tick():
global count
count += 1
print(count)
if count < 3:
root.after(10, tick)
else:
root.destroy()
root.after(10, tick)
root.mainloop()
Барориш:
1
2
3
Шиносаи баргашта имкон медиҳад даъвати ҳанӯз иҷронашударо бо after_cancel() бекор кунед. Ҳангоми таваққуфи аниматсия чанд занҷири параллели таймер насозед.
import tkinter as tk
root = tk.Tk()
root.withdraw()
timer = root.after(20, lambda: print("Набояд пайдо шавад"))
root.after_cancel(timer)
root.after(30, root.destroy)
root.mainloop()
print("Бекор шуд")
Барориш:
Бекор шуд
4. Соат чен мекунад, таймер экранро нав мекунад
Шумораи кадрҳо вақти дақиқ нест: системаи амалиётӣ метавонад коркардкунандаро дер иҷро кунад. time.monotonic() хониши соатеро медиҳад, ки ҳангоми танзими вақти тақвимӣ ба қафо намеравад. Фарқи ду хониш вақти гузаштаро бо сония медиҳад. Дар мисол хонишҳои пешакӣ додашударо мегирем, то барориш такроршаванда бошад.
start, now = 100.0, 102.75
elapsed = now - start
print(f"{elapsed:.2f}")
print(f"{7:02d}")
print(divmod(95, 60))
Барориш:
2.75
07
(1, 35)
divmod() ҳосили тақсим ва бақияи тақсими бутунро медиҳад, :02d бошад, адади бутунро бо сифр то ду ҷой пур мекунад. Инҳо ҷузъҳои форматбандиянд; формати пурраи сониясанҷро худатон ҷамъ мекунед.
Ҳангоми ҳаракат координатаҳо ва суръатро дар модел нигоҳ дошта, баъд ба холст гузаронед. Санҷиши девор бояд радиус ва масофаи дар як кадр тайшударо ба назар гирад. Расидан ба сарҳад ва гузаштан аз онро фарқ кунед; қоидаҳои дақиқ дар масъалаи тӯбча дода шудаанд.
5. Ҳисобкунак: матн, токенҳо, афзалият
Ифодаи чопшуда ҳоло сатр аст. Токен қисми маънодор аст: адад, аломати амал ё қавс. Таҳлилгар токенҳоро хонда, аз рӯйи қоидаҳо қиматро ҳисоб мекунад. Афзалият муайян мекунад, ки кадом амал қавитар мепайвандад: зарб пеш аз ҷамъ иҷро мешавад. Қавсҳо ифодаи дарунсохт медиҳанд, минуси унарӣ бошад, аломати як қиматро иваз мекунад.
import re
text = "6 + 2 * 5"
tokens = re.findall(r"\d+(?:\.\d+)?|[()+*/-]", text)
print(tokens)
print(6 + 2 * 5)
print((6 + 2) * 5)
print(18 / 3 / 2)
Барориш:
['6', '+', '2', '*', '5']
16
40
3.0
Ин қолаби омӯзишӣ танҳо токенҳоро ҷудо мекунад; тамоми ифодаро намесанҷад. Барои ҳисобкунак таҳлиле лозим аст, ки аломатҳои боқимондаро ҳам санҷад. Дар таҳлили рекурсивӣ (recursive descent) функсияҳо ба сатҳҳои афзалият мувофиқанд: expr бо ҷамъшавандаҳо, term бо зарбшавандаҳо ва factor бо адад, минус ё қавс кор мекунад. Функсияи қавсҳо метавонад боз таҳлили ифодаро даъват кунад: ҳамин тавр рекурсия пайдо мешавад.
Амалҳои як сатҳ аз чап ба рост иҷро мешаванд. Дар ҷамъ тартиби нодуруст баъзан ноаён мемонад, бинобар ин тарҳ ва тақсимро ҳам санҷед. eval() коди Python-ро иҷро мекунад ва барои майдони ҳисобкунак мувофиқ нест.
Дар дохил чӣ рӯй медиҳад
Холст рӯйхати объектҳо, намуд, координатаҳо ва хосиятҳои онҳоро нигоҳ медорад. Тағйири объект модели намоишро нав мекунад, аз нав кашиданро бошад, даври рӯйдодҳо иҷро мекунад. after() кори ояндаро ба навбат мегузорад, на ин ки риштаи алоҳида оғоз кунад. Қадами кӯтоҳи аниматсия моделро хонда, тағйир медиҳад, тасвирро нав мекунад ва қадами ояндаро таъйин мекунад.
Хатоҳои маъмул ва ислоҳи онҳо
canvas.move(ball, x, y)-ро таъйини ҷой мепиндоранд. Ин илова кардани ҷойивазкунӣ аст. Барои координатаҳои нави мутлақcoords()истифода баред.root.after(16, tick())tick-ро фавран даъват мекунад. Худи функсияро диҳед:root.after(16, tick).time.sleep(1)дар коркардкунанда навбатро мебандад ва равзана ҷавоб намедиҳад. Корро боafter()ба қадамҳои кӯтоҳ ҷудо кунед.create_oval(...)дар ҳар кадр объектҳои нав илова мекунад. Шиносаро нигоҳ дошта, объекти мавҷударо тағйир диҳед.- Ҳисобкунаки даъватҳо мисли
count * 0.1тадриҷан аз вақти воқеӣ дур мешавад. Фарқи хонишҳоиtime.monotonic()-ро чен кунед; таймерро барои навсозии экран гиред.
Ёднома
| Амал | Восита |
|---|---|
| Сохтани объект | create_line, create_rectangle, create_oval, create_text |
| Ҷойивазкунӣ / координатаҳои нав | move(item, dx, dy) / coords(item, ...) |
| Хосиятҳо / несткунӣ | itemconfig() / delete() |
| Даъвати мавқуф / бекоркунӣ | after(ms, f) / after_cancel(timer) |
| Чен кардани давомнокӣ | Фарқи хонишҳои time.monotonic() |
| Ҷудо кардани воҳидҳо / пур кардан бо сифр | divmod() / :02d |
| Таҳлили ифода | Токенҳо → сатҳҳои афзалият → қимат |