73 LISA: PySimpleGUI joonistamine

Sarnaselt tkinter-ile saab PySimpleGUI-s joonistada erinevaid kujundeid, määrata nende asukohta, suurust, värvi jne.

Vaatame samm-sammult, kuidas luua programmi, mis kuvab ekraanile graafikaakna koos taustapildi ja maja kujutisega.

Esmalt peame importima kõik PySimpleGUI klassid ja funktsioonid, nagu juba teame.

import PySimpleGUI as sg

Loome akna paigutuse. Sarnaselt tkinter-ile kasutame elementide paigutamise jaoks koordinaatteljestikku. Koordinaadid x ja y suurenevad vasakust nurgast selliselt:

Määrame sg.Graph()-i abil lõuendi suuruse, selle alumise vasaku nurga ning parema ülemise nurga koordinaadid (x,y). Samuti lisame lõuendi alla veel ühe rea, kuhu paneme nupu, millele vajutades suletakse programm.

PS! Pane tähele, et SimpleGUI-s saab määrata ainult alumise vasaku ning ülemise parema nurga! Seega, kuna meie tahame, et ülemise vasaku nurga koordinaadid oleksid (x=0,y=0), peame hoolikalt jälgima, missugused koordinaadid siin määrame:

paigutus = [[sg.Graph(
            canvas_size =(400, 400),
            graph_bottom_left=(0, 400),
            graph_top_right=(400, 0),
            key="lõuend")],
            [sg.Cancel('Välju')]]

Nüüd loome graafikaakna ning ka muutuja minu_lõuend, mille abil saame meie loodud lõuendi aknasse lisada.

aken = sg.Window("Joonistame!", paigutus)
aken.Finalize()

minu_lõuend = aken.Element("lõuend")

Sellesse muutujasse saame omakorda hakata lisama erinevaid elemente.

Esmalt võiksime lõuendile panna .png formaadis taustapildi, mis asub meie Pythoni failiga samas kaustas. Kuna tahame, et pilt kataks terve akna, määrame alguskohaks lõuendi ülemise vasaku nurga koordinaadid (x=0, y=0).

minu_lõuend.DrawImage(filename="minupilt.png", location=(0, 0))

PS! Sellisel kujul saab graafikaaknas kuvada ainult .png formaadis pilte! Kui tahaksime kasutada näiteks .jpg formaadis pilte, peaksime need enne kasutamist PIL mooduli abil .png formaati teisendama.

Selle jaoks peame importima PIL moodulist Image klassid ning seejärel saame avada oma pildi ning selle .png formaati teisendada:

from PIL import Image
fail = Image.open('minupilt.jpg')
fail = fail.save('minupilt.png')

Nüüd saamegi anda selle pildifaili .DrawImage argumendiks:

taustapilt = minu_lõuend.DrawImage(filename='minupilt.png', location=(0, 0))

On aeg hakata joonistama maja! Selle jaoks kasutame erinevaid kujundeid. Kujundite loomisel tuleb ära määrata nende alguspunkt (x,y) ning lõpppunkt (x,y) ning samuti saame määrata ka kujundi joone värvi ning värvi, millega tahame kujundi täita.

Näiteks, kui tahame luua ühe ristküliku, peame esmalt paika panema selle alumise vasakpoolse tipu ning seejärel ülemise vasakpoolse tipu koordinaadid (seega diagonaalsed tipud):

minu_lõuend.DrawRectangle((200,200), (350,380))

Nüüd lisamegi lõuendile erinevaid kujundeid:

#ristkülik
maja = minu_lõuend.DrawRectangle((200,200), (350,380), line_color='black', fill_color='darkgrey')

katus = minu_lõuend.DrawRectangle((180,200), (370,150), line_color='black', fill_color='darkgrey')

#punkt - määrame punkti keskpunkti koordinaadid (275,250) ning suuruse (50)
maja_aken = minu_lõuend.DrawPoint((275, 250), 50, color='blue')

uks = minu_lõuend.DrawRectangle((260, 380), (290,320), line_color='black', fill_color='brown')

Maja kõrvale võiksime lisada ka näiteks ühe inimese kriipsujuku näol.

Selleks kasutame .DrawLine((x,y), (x,y)), kus esimesteks koordinaatideks on joone alguspunkt ning teisteks joone lõpppunkt. Joone paksust saab ka muuta, kasutades näiteks width=2 saab joont paksemaks teha (vaikimisi on width väärtuseks 1, mis on kõige peenem joon).

#inimene
jalg = minu_lõuend.DrawLine((40, 370), (50, 340), color="black", width=2)
jalg2 = minu_lõuend.DrawLine((50, 340), (60, 370), color="black", width=2)
keha = minu_lõuend.DrawLine((50, 340), (50, 320), color="black", width=2)
pea = minu_lõuend.DrawOval((40, 300), (60, 320), fill_color="black")
käed = minu_lõuend.DrawLine((30, 330), (70, 330), color="black", width=2)

Programmi lõppu kirjutame juba tuttavad read:

while True:
    syndmus, v22rtused = aken.read()
    if syndmus == sg.WIN_CLOSED or syndmus == 'Välju':
            break
aken.close()

Ja meie maja ongi valmis! Proovi nüüd ka ise siin koodis muuta näiteks elementide suurust, värvi või asukohta.

Kogu programm näeb seega välja selline:

import PySimpleGUI as sg

paigutus = [
    [sg.Graph(
            canvas_size =(400, 400),
            graph_bottom_left=(0, 400),
            graph_top_right=(400, 0),
            key="lõuend")],
            [sg.Cancel('Välju')]]

aken = sg.Window("Joonistame!", paigutus)
aken.Finalize()
minu_lõuend = aken.Element("lõuend")

taustapilt = minu_lõuend.DrawImage(filename="minupilt.png", location=(0, 0))

maja = minu_lõuend.DrawRectangle((200,200), (350,380), line_color='black', fill_color='darkgrey')

katus = minu_lõuend.DrawRectangle((180,200), (370,150), line_color='black', fill_color='darkgrey')

maja_aken = minu_lõuend.DrawPoint((275, 250), 50, color='black')

uks = minu_lõuend.DrawRectangle((260, 380), (290,320), line_color='black', fill_color='brown')

#inimene
jalg = minu_lõuend.DrawLine((40, 370), (50, 340), color="black", width=2)
jalg2 = minu_lõuend.DrawLine((50, 340), (60, 370), color="black", width=2)
keha = minu_lõuend.DrawLine((50, 340), (50, 320), color="black", width=2)
pea = minu_lõuend.DrawOval((40, 300), (60, 320), fill_color="black")
käed = minu_lõuend.DrawLine((30, 330), (70, 330), color="black", width=2)

while True:
    syndmus, v22rtused = aken.Read()
    if syndmus == sg.WIN_CLOSED or syndmus == 'Välju':
        break
                
aken.close()

Ekraanile kuvatakse selline graafikaaken:

Joonistamise lisafunktsioonid

Tutvume paari lihtsa lisafunktsiooniga, mida meie joonistatud kujunditega teha saaks. Muudame elementide värve ja muudame pilte interaktiivsemaks, lisades võimaluse elemente liigutada.

1) Elemendi värvi muutmine

Lisame eelmise maja joonistamise näiteülesande juurde nupu, millele vajutades saab “toas tule põlema panna” ehk nupule vajutades muudetakse akende värv kollaseks. Teisele nupule vajutades saab “tuled jälle kustu panna”.

paigutus = [[sg.Graph(
            canvas_size =(400, 400),
            graph_bottom_left=(0, 400),
            graph_top_right=(400, 0),
            key="lõuend")],
            [sg.Text('Lisavalikud:')],
            [sg.Button('Tuled põlema!'), sg.Button('Tuled kustu!')],
            [sg.Cancel('Välju')]]

Nupuvajutuse töölepanemiseks lisame koodi lõpus olevasse while-tsüklisse tingimuse, et kui seda nuppu vajutatakse, muudetakse akende värvi.

if syndmus == 'Tuled põlema!':
        minu_lõuend.TKCanvas.itemconfig(maja_aken, fill = 'yellow')
if syndmus == 'Tuled kustu!':
        minu_lõuend.TKCanvas.itemconfig(maja_aken, fill = 'black')

Käivita programm ja proovi, kas nupuvajutused töötavad!

2) Elemendi asukoha muutmine

Kui on soov teha pilti natukene interaktiivsemaks, siis saame lisada veel kaks nuppu, millele vajutades saab elemente liigutada:

paigutus = [[sg.Graph(
            canvas_size =(400, 400),
            graph_bottom_left=(0, 400),
            graph_top_right=(400, 0),
            key="lõuend")],
            [sg.Text('Lisavalikud:')],
            [sg.Button('Muuda akna värvi')],
            [sg.Button('Liiguta inimest paremale'), sg.Button('Liiguta inimest vasakule')],
            [sg.Cancel('Välju')]]

Lisame uued tingimused while-tsüklisse. Inimese paremale liigutamise jaoks muudame kehaosade x-koordinaati 5 võrra, vasakule liigutamise jaoks -5 võrra. Kui tahaksime elementi liigutada üles-alla, peaksime muutma y-koordinaati; diagonaalis liigutamiseks aga mõlemat koordinaati.

if syndmus == 'Liiguta inimest paremale':
        minu_lõuend.MoveFigure(jalg, 5,0)
        minu_lõuend.MoveFigure(jalg2, 5,0)
        minu_lõuend.MoveFigure(keha, 5,0)
        minu_lõuend.MoveFigure(pea, 5,0)
        minu_lõuend.MoveFigure(käed, 5,0)
if syndmus == 'Liiguta inimest vasakule':
        minu_lõuend.MoveFigure(jalg, -5,0)
        minu_lõuend.MoveFigure(jalg2, -5,0)
        minu_lõuend.MoveFigure(keha, -5,0)
        minu_lõuend.MoveFigure(pea, -5,0)
        minu_lõuend.MoveFigure(käed, -5,0)

Katseta ja vaata, mis juhtub! Püüa pildile veel lisada (liigutatavaid) objekte, näiteks lisa veel juurde aknaid, korsten, katuse kaunistused, uksele aken (selle jaoks saad kasutada sg.DrawOval) jne. Näiteks võiks lõpptulemus välja näha selline:

Litsents

Icon for the Creative Commons Attribution 4.0 International License

Tarkvaraarendus. 2. trükk on loodud Eno Tõnisson, Tauno Palts, Kaarel Tõnisson, Heidi Meier, Merilin Säde, Ago Luberg, Birgy Lorenz, Einar Kivisalu, Meelis Antoi, ja Säde Mai Krusberg poolt Creative Commons Attribution 4.0 International License litsentsi alusel, kui pole teisiti märgitud.

Jaga seda raamatut