Riešenie úloh 10. cvičenia


  1. Riešenie:

    import tkinter
    
    def kresli(event):
        x, y = event.x, event.y
        canvas.create_line(x, y, x + 100, y, width=2)
    
    def zmaz(event=None):
        canvas.delete('all')
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<B1-Motion>', kresli)
    canvas.bind('<ButtonPress-3>', zmaz)
    tkinter.Button(text='Zmaž', command=zmaz).pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    r = 1
    farba = 'yellow'
    
    def kresli(event):
        global r
        x, y = event.x, event.y
        canvas.create_oval(x - r, y - r, x + r, y + r, fill=farba)
        r += .1
    
    def zmaz(event):
        global r
        r = 1
        canvas.delete('all')
    
    def zmen_farbu():
        global farba
        farba = f'#{random.randrange(256**3):06x}'
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<B1-Motion>', kresli)
    canvas.bind('<ButtonPress-3>', zmaz)
    tkinter.Button(text='Zmeň farbu', command=zmen_farbu).pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    zoznam = []
    
    def klik(event):
        zoznam.append((event.x, event.y))
        if len(zoznam) == 2:
            fill = f'#{random.randrange(256**3):06x}'
            canvas.create_rectangle(zoznam, fill=fill)
            zoznam.clear()
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<ButtonPress-1>', klik)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    zoznam = []
    
    def klik(event):
        xy = event.x, event.y
        zoznam.append(xy)
        canvas.create_text(xy, text='+')
        if len(zoznam) == 3:
            fill = f'#{random.randrange(256**3):06x}'
            canvas.create_polygon(zoznam, fill=fill)
            zoznam.pop(0)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<ButtonPress-1>', klik)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    zoznam = []
    
    def klik(event):
        x, y = event.x, event.y
        zoznam.append((x, y))
        canvas.create_text(x, y, text='+')
        x0, y0 = zoznam[0]
        if len(zoznam) > 2 and (x - x0) ** 2 + (y - y0) ** 2 < 25:
            fill = f'#{random.randrange(256**3):06x}'
            canvas.create_polygon(zoznam, fill=fill)
            zoznam.clear()
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<ButtonPress-1>', klik)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    zoznam = []       # momentálne vytvarané vrcholy
    polygony = []     # všetky nakreslené polygóny
    
    def klik(event):
        x, y = event.x, event.y
        zoznam.append((x, y))
        canvas.create_text(x, y, text='+', tag='+')
        x0, y0 = zoznam[0]
        if len(zoznam) > 2 and (x - x0) ** 2 + (y - y0) ** 2 < 25:
            fill = f'#{random.randrange(256**3):06x}'
            polygony.append(canvas.create_polygon(zoznam, fill=fill))
            zoznam.clear()
            canvas.delete('+')
    
    def zmaz():
        canvas.delete('all')
        zoznam.clear()
        polygony.clear()
    
    def zmen_farbu():
        if polygony:
            fill = f'#{random.randrange(256**3):06x}'
            canvas.itemconfig(polygony[-1], fill=fill)
    
    def spat():
        if polygony:
            canvas.delete(polygony.pop(0))
    
    canvas = tkinter.Canvas()
    canvas.pack(side='left')
    
    canvas.bind('<ButtonPress-1>', klik)
    tkinter.Button(text='Zmaž', command=zmaz).pack()
    tkinter.Button(text='Zmeň farbu', command=zmen_farbu).pack()
    tkinter.Button(text='Späť', command=spat).pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    def klik(event):
        x, y = event.x, event.y
        if x1 <= x <= x2 and y1 <= y <= y2:
            farba = farby.pop(0)
            farby.append(farba)
            canvas.itemconfig(obd, fill=farba)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    x1, y1, x2, y2 = 100, 50, 200, 100
    farby = ['blue', 'red', 'green', 'yellow']
    obd = canvas.create_rectangle(x1, y1, x2, y2, fill=farby[-1])
    
    canvas.bind('<ButtonPress>', klik)
    
    tkinter.mainloop()
    

    alebo pomocou canvas.tag_bind, ktorý zviaže udalosť len s daným objektom:

    import tkinter
    
    def klik(event):
        farba = farby.pop(0)
        farby.append(farba)
        canvas.itemconfig(obd, fill=farba)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    x1, y1, x2, y2 = 100, 50, 200, 100
    farby = ['blue', 'red', 'green', 'yellow']
    obd = canvas.create_rectangle(x1, y1, x2, y2, fill=farby[-1])
    
    canvas.tag_bind(obd, '<ButtonPress>', klik) # klikanie len do vnútra útvaru
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    cislo = [1]
    body = []
    
    def klik(event):
        xy = event.x, event.y
        body.append(xy)
        canvas.create_text(xy, text=cislo)
        cislo[0] += 1
    
    def zmaz():
        canvas.delete('all')
        cislo[0] = 1
        body.clear()
    
    def nakresli_ciaru():
        canvas.create_line(body)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<ButtonPress>', klik)
    tkinter.Button(text='Zmaž', command=zmaz).pack()
    tkinter.Button(text='Nakresli čiaru', command=nakresli_ciaru).pack()
    
    tkinter.mainloop()
    

    alebo len s jednou globálnou premennou:

    import tkinter
    
    body = []
    
    def klik(event):
        xy = event.x, event.y
        body.append(xy)
        canvas.create_text(xy, text=len(body))
    
    def zmaz():
        canvas.delete('all')
        body.clear()
    
    def nakresli_ciaru():
        canvas.create_line(body)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<ButtonPress>', klik)
    tkinter.Button(text='Zmaž', command=zmaz).pack()
    tkinter.Button(text='Nakresli čiaru', command=nakresli_ciaru).pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    def klik(event):
        x = event.x // 50 * 50
        y = event.y // 50 * 50
        farba = f'#{random.randrange(256**3):06x}'
        canvas.create_rectangle(x, y, x + 50, y + 50, fill=farba)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<ButtonPress>', klik)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    def klik(event):
        x, y = event.x, event.y
        vzd = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5
        if vzd < r:
            # f = int(255 * vzd / r)
            # farba = f'#{f:02x}{f:02x}{f:02x}'
            farba = '#' + 3 * f'{int(255 * vzd / r):02x}'
            canvas.itemconfig(kruh, fill=farba)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    r, x0, y0 = 120, 150, 130
    kruh = canvas.create_oval(x0 - r, y0 - r, x0 + r, y0 + r)
    canvas.bind('<ButtonPress>', klik)
    canvas.bind('<Motion>', klik)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    farba = 'blue'
    
    def tahaj(event):
        for i in range(20):
            x = event.x + random.randint(-30, 30)
            y = event.y + random.randint(-30, 30)
            canvas.create_oval(x - 2, y - 2, x + 2, y + 2,
                               fill=farba, width=0)
    
    def zmen_farbu(event=None):
        global farba
        farba = f'#{random.randrange(256**3):06x}'
        vypis['text'] = f'farba: {farba}'
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<B1-Motion>', tahaj)
    tkinter.Button(text='Zmeň farbu', command=zmen_farbu).pack()
    vypis = tkinter.Label(text='farba: blue')
    vypis.pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    xy = []
    
    def klik(event):
        global usecka
        xy[:] = [event.x, event.y] * 2
        usecka = canvas.create_line(xy, width=hrubka.get())
    
    def tahaj(event):
        xy[2:4] = [event.x, event.y]
        canvas.coords(usecka, xy)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<B1-Motion>', tahaj)
    canvas.bind('<ButtonPress-1>', klik)
    hrubka = tkinter.Scale(orient='horizontal', from_=1, to=20)
    hrubka.pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    xy = []
    zoz = []        # zoznam všetkých obdĺžnikov
    
    def klik(event):
        xy[:] = [event.x, event.y] * 2
        farba = f'#{random.randrange(256**3):06x}'
        zoz.append(canvas.create_rectangle(xy, fill=farba))
    
    def tahaj(event):
        xy[2:4] = [event.x, event.y]
        canvas.coords(zoz[-1], xy)
    
    def undo():
        if zoz:
            canvas.delete(zoz.pop())
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    canvas.bind('<B1-Motion>', tahaj)
    canvas.bind('<ButtonPress>', klik)
    tkinter.Button(text='Undo', command=undo).pack()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    dxy = []            # posun kliknutého bodu
    
    def klik(event):
        x, y = canvas.coords(stvorec)[:2]
        dxy[:] = dx, dy = event.x - x, event.y - y
        if dx < 0 or dx > 50 or dy < 0 or dy > 50:
            dxy.clear()
    
    def tahaj(event):
        if dxy:
            x, y = event.x - dxy[0], event.y - dxy[1]
            canvas.coords(stvorec, x, y, x + 50, y + 50)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    stvorec = canvas.create_rectangle(100, 50, 100 + 50, 50 + 50,
                                      fill='red')
    canvas.bind('<B1-Motion>', tahaj)
    canvas.bind('<ButtonPress-1>', klik)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    dxy = []
    
    def klik(event):
        global ktory
        for utvar in reversed(utvary):
            x1, y1, x2, y2 = canvas.coords(utvar)
            dxy[:] = dx, dy = event.x - x1, event.y - y1
            if 0 <= dx < x2 - x1 and 0 <= dy < y2 - y1:
                ktory = utvar
                canvas.bind('<B1-Motion>', tahaj) # až teraz zviaže udalosť
                return
    
    def tahaj(event):
        x1, y1, x2, y2 = canvas.coords(ktory)
        sir, vys = x2 - x1, y2 - y1
        x1, y1 = event.x - dxy[0], event.y - dxy[1]
        canvas.coords(ktory, x1, y1, x1 + sir, y1 + vys)
    
    def pusti(event):
        canvas.unbind('<B1-Motion>')        # zruší zviazanie udalosti
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    utvary = [canvas.create_rectangle(100, 50, 200, 100, fill='red'),
              canvas.create_rectangle(250, 100, 350, 200, fill='blue'),
              canvas.create_rectangle(50, 80, 220, 130, fill='yellow'),
              # tu môže byť ľubovoľný počet obdĺžnikov
             ]
    canvas.bind('<ButtonPress-1>', klik)
    canvas.bind('<ButtonRelease-1>', pusti)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    
    text = ''
    
    def klaves(event):    # event.char: '\r' return, '\b' backspace
        global text
        if 'a' <= event.char.lower() <= 'z' or event.char in ' \r':
            text += event.char
            canvas.itemconfig(riadky, text=text)
        elif event.char == '\b':
            text = text[:-1]
            canvas.itemconfig(riadky, text=text)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    riadky = canvas.create_text(190, 130, fill='blue', font='arial 30')
    canvas.bind_all('<KeyPress>', klaves)
    
    tkinter.mainloop()
    

    alebo pomocou canvas.itemcget(...), ktorá vráti momentálnu hodnotu atribútu 'text' v texte:

    import tkinter
    
    def klaves(event):    # event.char: '\r' return, '\b' backspace
        if 'a' <= event.char.lower() <= 'z' or event.char in ' \r':
            text = canvas.itemcget(riadky, 'text') + event.char
            canvas.itemconfig(riadky, text=text)
        elif event.char == '\b':
            text = canvas.itemcget(riadky, 'text')[:-1]
            canvas.itemconfig(riadky, text=text)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    riadky = canvas.create_text(190, 130, fill='blue', font='arial 30')
    canvas.bind_all('<KeyPress>', klaves)
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    from math import sin, cos, radians
    
    def timer():
        global uhol
        uhol += 10
        x = x0 + r * cos(radians(uhol))
        y = y0 + r * sin(radians(uhol))
        canvas.coords(bodka, x - 5, y - 5, x + 5, y + 5)
        canvas.after(cas.get(), timer)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    cas = tkinter.Scale(orient='horizontal', from_=50, to=1000,
                        resolution=50)
    cas.pack()
    
    r, x0, y0 = 100, 150, 120
    canvas.create_oval(x0 - r, y0 - r, x0 + r, y0 + r)
    bodka = canvas.create_oval(x0 + r - 5, y0 - 5, x0 + r + 5, y0 + 5,
                               width=0, fill='red')
    uhol = 0
    timer()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    from math import sin, cos, radians
    
    moze_cerveny = moze_modry = True
    
    def timer():
        global uhol1, uhol2
        if moze_cerveny:
            uhol1 += 10
            x = x0 + r * cos(radians(uhol1))
            y = y0 + r * sin(radians(uhol1))
            canvas.coords(bodka1, x - 5, y - 5, x + 5, y + 5)
        if moze_modry:
            uhol2 += 15
            x = x0 + r * cos(radians(uhol2))
            y = y0 + r * sin(radians(uhol2))
            canvas.coords(bodka2, x - 7, y - 7, x + 7, y + 7)
        canvas.after(100, timer)
    
    def cerveny():
        global moze_cerveny
        moze_cerveny = not moze_cerveny
    
    def modry():
        global moze_modry
        moze_modry = not moze_modry
    
    canvas = tkinter.Canvas()
    canvas.pack(side='left')
    tkinter.Button(text='Červený', command=cerveny).pack()
    tkinter.Button(text='Modrý', command=modry).pack()
    
    r, x0, y0 = 100, 150, 120
    canvas.create_oval(x0 - r, y0 - r, x0 + r, y0 + r)
    bodka1 = canvas.create_oval(x0 + r - 5, y0 - 5, x0 + r + 5, y0 + 5,
                                width=0, fill='red')
    bodka2 = canvas.create_oval(x0 + r - 7, y0 - 7, x0 + r + 7, y0 + 7,
                                width=0, fill='blue')
    uhol1 = uhol2 = 0
    timer()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import time
    
    def timer():
        global cas
        cas += 1
        dsek, sek = cas % 10, cas // 10
        sek, min = sek % 60, sek // 60
        min, hod = min % 60, min // 60
        canvas.itemconfig(text, text=f'{hod}:{min:02}:{sek:02}.{dsek}')
        canvas.after(100, timer)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    text = canvas.create_text(190, 130, fill='blue', font='consolas 40')
    h, m, s = time.localtime()[3:6]
    cas = h*36000 + m*600 + s*10
    timer()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    interval, r = 1000, 20
    
    def timer():
        global x0, y0
        x0 = random.randrange(r, 380 - r)
        y0 = random.randrange(r, 260 - r)
        canvas.coords(kruh, x0 - r, y0 - r, x0 + r, y0 + r)
        canvas.after(interval, timer)
    
    def klik(event):
        global skore
        x, y = event.x, event.y
        if (x-x0) ** 2 + (y-y0) ** 2 <= r ** 2:
            skore += 10
        else:
            skore -= 1
        label_skore['text'] = f'skore = {skore}'
    
    canvas = tkinter.Canvas()
    canvas.pack(side='left')
    canvas.bind('<ButtonPress>', klik)
    label_skore = tkinter.Label(text='skore =   ')
    label_skore.pack()
    tkinter.Label(text=f'spomalenie = {interval}').pack()
    tkinter.Label(text=f'velkost = {r}').pack()
    
    kruh = canvas.create_oval(0, 0, 0, 0, fill='light blue')
    skore = 0
    timer()
    
    tkinter.mainloop()
    

  1. Riešenie:

    import tkinter
    import random
    
    kruhy = []
    
    def timer():
        i = 0
        while i < len(kruhy):
            kruh = kruhy[i]
            x1, y1, x2, y2 = canvas.coords(kruh)
            r, x, y = (x2 - x1) / 2, (x1 + x2) / 2, (y1 + y2) / 2
            if r >= 1:
                r -= 1
                canvas.coords(kruh, x - r, y - r, x + r, y + r)
                i += 1
            else:
                canvas.delete(kruh)
                del kruhy[i]
        canvas.after(100, timer)
    
    def klik(event):
        r, x, y = 50, event.x, event.y
        farba = f'#{random.randrange(256**3):06x}'
        kruh = canvas.create_oval(x - r, y - r, x + r, y + r,
                                  fill=farba, width=0)
        kruhy.append(kruh)
    
    canvas = tkinter.Canvas()
    canvas.pack()
    
    timer()
    canvas.bind('<ButtonPress>', klik)
    #canvas.bind('<B1-Motion>', klik)
    
    tkinter.mainloop()