23 Lisalugemine. Funktsiooni graafik, liikuvad pildid
See peatükk on mõeldud huvilistele, kes tahavad kasutada Tkinterit funktsioonide graafikute joonistamiseks ning piltide liikumise loomiseks.
Funktsiooni graafik
Koostame programmi, mis joonistab mõne meie valitud (matemaatilise) funktsiooni (nt y=x3) graafiku.
Kuigi Tkinter sobib hästi graafikute joonistamiseks, tekitab mõningast ebamugavust teistmoodi koordinaatide süsteem – matemaatikas oleme harjunud, et y kasvab ülespoole, mitte alla ning koordinaatide alguspunkt on harjumuspäraselt olnud pigem joonise keskel. Võtame abiks klassi Canvas funktsiooni move
, mis võimaldab tahvlil olevaid objekte horisontaalset ja vertikaalset telge mööda ümber tõsta. Seega paigutame kõik objektid harilikku koordinaadistikku, seejärel rakendame funktsiooni
. Peegelduse x-telje suhtes korraldame sellega, et funktsiooni väärtuste kogumisel kogume y asemel -y. Näiteprogramm joonistab funktsiooni y=x graafiku:move
Näiteprogramm. y=x graafik
from tkinter import * raam = Tk() # tahvli laius w = 500 # tahvli pikkus h = 500 tahvel = Canvas(raam, width=w, height=h, bg="white") # vertikaalne telg tahvel.create_line(0, h/2, 0, -h/2, arrow=LAST) # horisontaalne telg tahvel.create_line(-w/2, 0, w/2, 0, arrow=LAST) # joonistame lõigud (x1,f(x1)) - (x2,f(x2)) x1 = -w//2 while x1 < w//2: x2 = x1+1 # olgu alguseks lineaarne funktsioon y1 = x1 y2 = x2 # -y on selleks, et peegeldada x-telje suhtes tahvel.create_line(x1, -y1, x2, -y2) x1 += 1 # nihutame kõik objektid 250px võrra paremale ja alla tahvel.move(ALL, w/2, h/2) tahvel.pack() raam.mainloop()
Katseta programmi ka teiste funktsioonidega (5x, x**3 jne).
Liikuvad kujutised
Proovime joonistada osutitega kella, mis ennast aja jooksul värskendaks. Võrreldes eelmiste ülesannetega, kus tegemist oli sisuliselt staatiliste kujutistega, on nüüd tarvis muuta graafikaobjektide olekuid rakenduse töö ajal.
Graafikaobjektide loomisel saab neile anda unikaalseid nimesid, mille järgi saab need hiljem tahvlil üles leida, nt
id
=
tahvel.create_line(x0,y0,...,xn,yn)
Kasutades nime saab objekti näiteks kustutada, nihutada või muuta tema argumente. Objektidega manipuleerimiseks kasutame klassis Canvas defineeritud meetodeid.
# kustutamine tahvel.delete(id) # nihutamine tahvel.move(id, x, y) # objekti argumentide tagastamine tahvel.itemcget(id, "width") # koordinaatide uuendamine tahvel.coords(id, x0,y0,...,xn,yn )
Selles ülesandes huvitab meid viimane meetod, mille abil me saame osutite positsiooni uuendada. Tekitame uue raami ja tahvli. Kella keskpunkt olgu tahvli keskel.
from tkinter import * raam = Tk() raam.title("Kell") # tahvli laius w = 500 # tahvli pikkus h = 500 tahvel = Canvas(raam, width=w, height=h, bg="white") # kella raam tahvel.create_oval(10,10,w-10,h-10) # kella keskpunkt tahvel.create_oval(w/2-5,h/2-5,w/2+5,h/2+5,fill="black")
Joonistame sekundiosuti (mis on sirgjoon) ja salvestame tema andmed muutujasse sek_id
:
sek_id = tahvel.create_line(w/2,h/2,w/2,20,fill="red")
Kuna osuti üks ots on fikseeritud kella keskel, siis huvitavad meid ainult liikuva otsa koordinaadid mingil ajahetkel t. Kui on antud sekundite arv sekundid,
siis on võimalik arvutada vastavad punkti koordinaadid x ja y:
from math import * # osuti liikuva tipu koordinaadid # arvutame sekundiosuti pikkuse r = min(w/2,h/2)-20 # arvutame x koordinaadi x = r*cos(pi/2-sekundid/60.0*2*pi) # arvutame y koordinaadi y = -r*sin(pi/2-sekundid/60.0*2*pi)
Järgmise sammuna loome funktsiooni, mis loeb jooksvalt aega ja uuendab sekundiosuti positsiooni. Uus funktsioon luuakse võtmesõna
abil, funktsiooni sisu on taandatud. Täpsemalt käsitleme seda hilisemates peatükkides.def
import time def uuenda(): # loeme jooksva sekundi sekundid = time.localtime().tm_sec # osuti liikuva tipu koordinaadid # arvutame sekundiosuti pikkuse r = min(w/2,h/2)-20 # arvutame x koordinaadi x = r*cos(pi/2-sekundid/60.0*2*pi) # arvutame y koordinaadi y = -r*sin(pi/2-sekundid/60.0*2*pi) # uuendame osuti positsiooni tahvel.coords(sek_id, 0, 0, x, y) # nihutame keskele tahvel.move(sek_id, w/2, h/2) # ootame 1 sekundi ja siis uuendame kellaaega uuesti raam.after(1000, uuenda)
Kutsume funktsiooni
välja enne Tkinteri põhitsüklisse sisenemist:uuenda
uuenda() tahvel.pack() raam.mainloop()
Kokkupandud kood on järgmine:
Näiteprogramm. Osutitega kell
from tkinter import * from math import * import time raam = Tk() raam.title("Kell") # tahvli laius w = 500 # tahvli pikkus h = 500 tahvel = Canvas(raam, width=w, height=h, bg="white") # kella raam tahvel.create_oval(10,10,w-10,h-10) # kella keskpunkt tahvel.create_oval(w/2-5,h/2-5,w/2+5,h/2+5,fill="black") sek_id = tahvel.create_line(w/2,h/2,w/2,20,fill="red") def uuenda(): # loeme jooksva sekundi sekundid = time.localtime().tm_sec # osuti liikuva tipu koordinaadid # arvutame sekundiosuti pikkuse r = min(w/2,h/2)-20 # arvutame x koordinaadi x = r*cos(pi/2-sekundid/60.0*2*pi) # arvutame y koordinaadi y = -r*sin(pi/2-sekundid/60.0*2*pi) # uuendame osuti positsiooni tahvel.coords(sek_id, 0, 0, x, y) # nihutame keskele tahvel.move(sek_id, w/2, h/2) #ootame 1 sekundi ja siis uuendame kellaaega uuesti raam.after(1000, uuenda) uuenda() tahvel.pack() raam.mainloop()
Täienda kella. Lisa minuti- ja tunniosuti, mis samuti muudaksid aja jooksul oma positsiooni.
Palun kommenteeri seda materjali Google’i küsimustikus.