20. hodina - Kreslenie myšou


Naučíme sa zábavný spôsob kreslenia do grafickej plochy pomocou myši.

  1. Vyskúšaj takúto grafickú aplikáciu:

    import tkinter
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    def klik(mys):
        print(mys.x, mys.y)
    
    canvas.bind('<B1-Motion>', klik)
    

    Pribudol tu nový príkaz canvas.bind, pomocou ktorého bude odteraz grafická plocha vedieť, čo má robiť, keď nad ňou zatlačíme ľavé tlačidlo myši a s myšou potom ťaháme. V textovom okne sa začnú vypisovať dvojice celých čísel. Vedeli by ste zistiť, čo sú to za čísla?


  1. Zápis mys.x a mys.y v predchádzajúcom príklade označuje x-ovú a y-ovú súradnicu kliknutého miesta v grafickej ploche. Namiesto príkazu print v podprograme klik zapíš vykreslenie znaku '*' pomocou canvas.create_text. Znak by sa mal vypísať na pozíciu kliknutia myšou:

    import tkinter
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    def klik(mys):
        ________________________________________
    
    canvas.bind('<B1-Motion>', klik)
    

    Program teraz pri ťahaní myšou kreslí malé hviezdičky. Pomocou parametrov font='...' a fill='...' môžeš tieto znaky zväčšiť na veľkosť 50, resp. zmeniť ich farbu na červenú. Teraz by sa dalo vytvoriť napríklad takýto obrázok:

    _images/20_01.png

    Pokús sa takto nakresliť aj niečo zaujímavejšie.


  1. Pomocou canvas.create_oval(x-5, y-5, x+5, y+5) vieš nakresliť malý kruh so stredom (x, y) a s polomerom 5. V predchádzajúcom programe namiesto príkazu canvas.create_text použi kreslenie malého kruhu. Teraz by sa namiesto znakov '*' mali na kliknuté miesta kresliť kruhy, napríklad:

    _images/20_02.png

    Teraz zmeň polomer kreslených kruhov napríklad na hodnotu 30. Ako sa zmenia kreslené kruhy? Čo sa ešte muselo zmeniť, aby sa dal kresliť takýto obrázok?

    _images/20_03.png

  1. Podprogram klik, skôr ako nakreslí farebný krúžok, môže sa pomocou príkazu vetvenia rozhodnúť, či to bude červený alebo zelený krúžok. Oprav ho tak, aby sa krúžky s x-ovou súradnicou menšou ako 150 kreslili červené inak sa nakreslia zelené. Môžeš to vidieť na tomto obrázku:

    _images/20_04.png

  1. Opäť budeš upravovať podprogram klik, ale tak, aby okrem modrého krúžku s polomerom 5 nakreslil aj rovnakoveľký žltý, ale so stredom posunutým o 15 vpravo (k x-ovej súradnici pripočítaš 15). Teraz pri ťahaní myšou vzníká takýto efekt:

    _images/20_05.png

  1. Do svojho programu vlož tieto vyznačené riadky:

    import tkinter
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    def klik(mys):
        ...
        ...
    
    def zmaz(mys):
        canvas.delete('all')
    
    canvas.bind('<B1-Motion>', klik)
    canvas.bind('<ButtonPress-3>', zmaz)
    

    Teraz by malo všetko fungovať rovnako, ale program bude reagovať aj na kliknutie do grafickej plochy pravým tlačidlom myši. Vyskúšaj niečo do plochy nakresliť a potom zatlač pravé tlačidlo. Môžeš to opakovať aj viackrát. Použil si tu nový príkaz canvas.delete('all'), pomocou ktorého sa z grafickej plochy vymaže doterajšia kresba.


  1. Teraz sa naučíme nový grafický príkaz canvas.create_line(x1, y1, x2, y2). Pomocou ktorého sa nakreslí jednoduchá čiara (úsečka) z bodu (x1, y1) do bodu (x2, y2). Vyskúšaj:

    import tkinter
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    def klik(mys):
        canvas.create_line(150, 100, mys.x, mys.y)
    
    def zmaz(mys):
        canvas.delete('all')
    
    canvas.bind('<B1-Motion>', klik)
    canvas.bind('<ButtonPress-3>', zmaz)
    

    Dostaneš napríklad takýto obrázok:

    _images/20_06.png

    Pri ťahaní myšou sa kreslia úsečky z bodu (150, 100) do momentálnej pozície myši. Preto majú všetky tieto úsečky spoločný jeden vrchol. Dokážeš nakresliť aj takéto červené srdce?

    _images/20_07.png

    Farbu úsečky nastavíš rovnako ako napríklad farbu textu v canvas.create_text alebo farbu výplne v canvas.create_oval.


  1. Kreslenie úsečiek oprav tak, aby každá začínala na pozícii myši ((mys.x, mys.y)) a končila o 50 smerom nahor (y-ová súradnica konca úsečky bude o 50 zmenšená). Teraz nakreslíš napríklad:

    _images/20_08.png

  1. Do riešenia predchádzajúcej úlohy dopíš nakreslenie červeného krúžku na konci každej úsečky. Teraz by sa malo kresliť napríklad takto:

    _images/20_09.png

  1. Ďalší program využije náhodné vytváranie farieb pomocou:

    farba = random.choice(['red', 'yellow', 'blue', 'green'])
    

    Podprogram klik nakreslí obdĺžnik, ktorého ľavý horný roh bude vždy (10, 10) a pravý bude pozícia myši (mys.x, mys.y). Tento obdĺžnik bude zafarbený náhodne zvolenou farbou (napríklad jednou zo štyroch). Pri ťahaní myšou by sa ti mohol podariť podobný obrázok:

    _images/20_10.png
  2. Opäť bude podprogram klik kresliť červené krúžky, ale teraz ich nakreslí naraz 10 tesne vedľa seba: prvý krúžok ja na pozícii myši a každý ďalší má o 10 posunutý vpravo svoj stred (teda x-ovú súradnicu zväčší o 10). Teraz sa dá nakresliť napríklad toto:

    _images/20_11.png
  3. (*) Zadefinuj podprogram klik tak, aby vznikol efekt spreja. Bude sa to robiť takto:

    • najprv sa náhodne zvolía dve čísla dx a dy z intervalov <-30, 30> (pomocou random.randint(-30, 30))

    • táto dvojica čísel vyjadruje posunutie nakreslenej farebnej bodky oproti pozície myši (teda pozícia (mys.x+dx, mys.y+dy))

    • na túto posunutú pozíciu nakresli bodku napríklad pomocou canvas.create_text ako znak '+'

    • toto pri každom kliknutí zopakuj 50-krát, čím sa nakreslí 50 malých znakov '+', ktoré nebudú veľmi ďaleko od kliknutého miesta

    • ako farbu zvol napríklad farba = 'blue' a toto priradenie nezapíšeš do podprogramu klik ale do riadku ešte pred canvas.bind

    Môže vzniknúť takýto obrázok:

    _images/20_12.png