How do I make a button draw something new on a screen with Tkinter?

Asked

Viewed 329 times

1

I tried to make a data simulator in Python with Tkinter that shows the data layout in the window after scrolling. For this, I defined a function that generates a random number from 1 to 6 and draws the die side on a screen depending on the number that came out and related this function to a button. The problem is that when I press the button, the function is not called or called but does not change the screen.

import tkinter as tk
import random as rd 

def rolar_dado( canvas ):
    rand = rd.randint(1, 6)
    if rand == 1:
        dot = canvas.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 2:
        dot = canvas.create_oval(23, 23, 37, 37, fill='black')
        dot2 = canvas.create_oval(63, 63, 77, 77, fill='black')
    elif rand == 3:
        dot = canvas.create_oval(23, 23, 37, 37, fill='black')
        dot2 = canvas.create_oval(63, 63, 77, 77, fill='black')
        dot3 = canvas.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 4:
        dot = canvas.create_oval(23, 23, 37, 37, fill='black')
        dot2 = canvas.create_oval(63, 63, 77, 77, fill='black')
        dot3 = canvas.create_oval(23, 63, 37, 77, fill='black')
        dot4 = canvas.create_oval(63, 23, 77, 37, fill='black')
    elif rand == 5:
        dot = canvas.create_oval(23, 23, 37, 37, fill='black')
        dot2 = canvas.create_oval(63, 63, 77, 77, fill='black')
        dot3 = canvas.create_oval(23, 63, 37, 77, fill='black')
        dot4 = canvas.create_oval(63, 23, 77, 37, fill='black')
        dot5 = canvas.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 6:
        dot = canvas.create_oval(23, 23, 37, 37, fill='black')
        dot2 = canvas.create_oval(63, 63, 77, 77, fill='black')
        dot3 = canvas.create_oval(23, 63, 37, 77, fill='black')
        dot4 = canvas.create_oval(63, 23, 77, 37, fill='black')
        dot5 = canvas.create_oval(23, 43, 37, 57, fill='black')
        dot6 = canvas.create_oval(63, 43, 77, 57, fill='black')


root = tk.Tk()

c = tk.Canvas(root, height = 100, width = 100)
square = c.create_rectangle(10, 10, 90, 90, fill='white')
c.pack()

b = tk.Button(root, text='Rolar', command = rolar_dado(c))
b2 = tk.Button(root, text='Sair', command=root.destroy)

b.pack(side=tk.LEFT)
b2.pack(side=tk.RIGHT)

root.mainloop()

1 answer

1


The way your code is structured the canvas widget is being passed to the method as argument, in this case you will have to use an anonymous function (lambda) in the parameter command (callback) button.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Canvas."""
import random as rd
import tkinter as tk


def rolar_dado(canvas):
    rand = rd.randint(1, 6)

    # Exibindo o valor para confereir.
    print(rand)

    # Limpando a área de desenho.
    canvas.delete(tk.ALL)

    # Desenhando novamente.
    canvas.create_rectangle(10, 10, 90, 90, fill='white')
    if rand == 1:
        canvas.delete()
        canvas.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 2:
        canvas.create_oval(23, 23, 37, 37, fill='black')
        canvas.create_oval(63, 63, 77, 77, fill='black')
    elif rand == 3:
        canvas.create_oval(23, 23, 37, 37, fill='black')
        canvas.create_oval(63, 63, 77, 77, fill='black')
        canvas.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 4:
        canvas.create_oval(23, 23, 37, 37, fill='black')
        canvas.create_oval(63, 63, 77, 77, fill='black')
        canvas.create_oval(23, 63, 37, 77, fill='black')
        canvas.create_oval(63, 23, 77, 37, fill='black')
    elif rand == 5:
        canvas.create_oval(23, 23, 37, 37, fill='black')
        canvas.create_oval(63, 63, 77, 77, fill='black')
        canvas.create_oval(23, 63, 37, 77, fill='black')
        canvas.create_oval(63, 23, 77, 37, fill='black')
        canvas.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 6:
        canvas.create_oval(23, 23, 37, 37, fill='black')
        canvas.create_oval(63, 63, 77, 77, fill='black')
        canvas.create_oval(23, 63, 37, 77, fill='black')
        canvas.create_oval(63, 23, 77, 37, fill='black')
        canvas.create_oval(23, 43, 37, 57, fill='black')
        canvas.create_oval(63, 43, 77, 57, fill='black')


root = tk.Tk()

c = tk.Canvas(root, height=100, width=100)
c.create_rectangle(10, 10, 90, 90, fill='white')
c.pack()

# Utilizando função anonima para chamar o método.
b = tk.Button(root, text='Rolar', command=lambda: rolar_dado(c))
b.pack(side=tk.LEFT)

b2 = tk.Button(root, text='Sair', command=root.destroy)
b2.pack(side=tk.RIGHT)

root.mainloop()

To nay use the anonymity function (lambda), you would have to restructure the code so that the widget is above the function.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Canvas."""
import random as rd
import tkinter as tk

root = tk.Tk()

c = tk.Canvas(root, height=100, width=100)
c.create_rectangle(10, 10, 90, 90, fill='white')
c.pack()


def rolar_dado():
    rand = rd.randint(1, 6)
    print(rand)
    c.delete(tk.ALL)
    c.create_rectangle(10, 10, 90, 90, fill='white')
    if rand == 1:
        c.delete()
        c.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 2:
        c.create_oval(23, 23, 37, 37, fill='black')
        c.create_oval(63, 63, 77, 77, fill='black')
    elif rand == 3:
        c.create_oval(23, 23, 37, 37, fill='black')
        c.create_oval(63, 63, 77, 77, fill='black')
        c.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 4:
        c.create_oval(23, 23, 37, 37, fill='black')
        c.create_oval(63, 63, 77, 77, fill='black')
        c.create_oval(23, 63, 37, 77, fill='black')
        c.create_oval(63, 23, 77, 37, fill='black')
    elif rand == 5:
        c.create_oval(23, 23, 37, 37, fill='black')
        c.create_oval(63, 63, 77, 77, fill='black')
        c.create_oval(23, 63, 37, 77, fill='black')
        c.create_oval(63, 23, 77, 37, fill='black')
        c.create_oval(43, 43, 57, 57, fill='black')
    elif rand == 6:
        c.create_oval(23, 23, 37, 37, fill='black')
        c.create_oval(63, 63, 77, 77, fill='black')
        c.create_oval(23, 63, 37, 77, fill='black')
        c.create_oval(63, 23, 77, 37, fill='black')
        c.create_oval(23, 43, 37, 57, fill='black')
        c.create_oval(63, 43, 77, 57, fill='black')


b = tk.Button(root, text='Rolar', command=rolar_dado)
b2 = tk.Button(root, text='Sair', command=root.destroy)

b.pack(side=tk.LEFT)
b2.pack(side=tk.RIGHT)

root.mainloop()

Notice that I removed the variables that were created and were not being used.

Regarding the issue of not changing it is because the code was not clearing the drawing area (delete()), basically one circle was getting over the other.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.