Időzítő
Az előző fejezetekben megtanultuk, hogyan tudunk a klikkelés helyére színes köröket rajzolni valamilyen feltétel szerint. Ha több kört szeretnénk, akkor többször kell klikkelni, vagy megoldható egy for ciklussal is, hogy egy klikkre több kör jelenjen meg.
For ciklust abban az esetben célszerű használni, ha előre tudjuk, mennyiszer kell lefutnia a ciklusnak - ezért is hívjuk kötött lépésszámú ciklusnak. Viszont vannak esetek, mikor nem tudjuk előre, hogy hányszor fog lefutni a ciklus, de ismételtetni szeretnénk néhány utasítást bizonyos időintervallumban. Ilyenkor időzítőt (timer) érdemes használni. Erre szolgál a canvas.after(idő, eljárás) utasítás, ahol meg kell adnunk, mennyi ideig várakozzon a program (ezredmásodpercben), és utána milyen eljárást hajtson végre.
import tkinter
from random import *
canvas = tkinter.Canvas()
canvas.pack()
def kor():
x = randrange(450)
y = randrange(320)
if 100<x<150 and 50<y<100:
canvas.create_oval(x-5, y-5, x+5, y+5, fill='green')
else:
canvas.create_oval(x-5, y-5, x+5, y+5, fill='yellow')
canvas.after(100, kor)
kor()
A program futtatásakor egyszer hívjuk a kor() eljárást, ami az időzítőnek köszönhetően addig fog ismétlődni, amíg be nem zárjuk a programot - 100 ezredmásodpercenként, vagyis 0,1 másodpercenként hívja a kor eljárást.
Egy programon belül több időzítőt is használhatunk, mindegyik a maga eljárását fogja ismételni függetlenül a másiktól.

A következő program néhány labdát (kört) rajzol egymás alá:
def labda():
global y
canvas.create_oval(x-5, y-5, x+5, y+5)
y = y+5
if y<250:
canvas.after(100, labda)
x = 200
y = 5
labda()
A programunkban két változónk van: x és y. Mindkettő globális változó, ezért a labda eljárásunkban nem változtathatjuk az értéküket, mint az eddigiekben megszoktuk. Meg kell mondanunk a programnak, hogy itt egy globális változó értékét szeretnénk változtatni, global y. Ezután az y = y + 5 utasítás már a helyes változónak az értékét fogja növelni.
A globális változókat az egész programban használhatjuk. Pl az y változó ugyanaz a változó a főprogramban és a ladba eljárásban is.
A helyi változók minden programrészletben más-más értékkel rendelkezhetnek még ha ugyanaz a nevük is. Pl. az előző programban, ahol kor() és negyzet() eljárásunk is van, mindkettőnek van x és y nevű helyi változója. Van a kor()-nek is x és a negyzet()-nek is x, és ezek egymástól függetlenek.
A labda() eljárásban olyan időzítőt hoztunk létre, amely nem a végtelenségig fog ismétlődni, hanem amíg a feltétel teljesül.
Ha lefuttatjuk a programot, láthatjuk. hogy az összes "labda" látható marad. Ha animációt szeretnénk készíteni, akkor mindig csak az aktuális állapotnak kell kirajzolva lennie, az előzőt le kell törölni. Így módosítsuk az eljárásunkat:
def labda():
global y
canvas.delete('all')
canvas.create_oval(x-5, y-5, x+5, y+5)
y = y+5
if y<250:
canvas.after(100, labda)
A canvas.delete('all') utasítás minden kirajzolt elemet töröl a vászonról. Ha ezt az eljárásunk elejére írjuk, akkor csak az aktuális állapotot fogjuk látni kirajzolódni.
Kérdések
- Mi fog történni, ha felcseréljük delete és create_oval utasításokat?
- Milyen koordinátákra rajzolódik ki az utolsó labda?
- Mit fog csinálni a program, ha a feltételt megváltoztatjuk erre: y == 250?
- Mit fog csinálni a program, ha az y-t 6-tal növeljük és a feltétel y == 250 lesz?
