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

1

I tried to make a data simulator in Python with Tkinter that shows the layout of the die in the window after rolling. For this, I defined a function that generates a random number from 1 to 6 and draws the data side on a screen depending on the number that came out and related that 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()
    
asked by anonymous 31.08.2018 / 02:37

1 answer

1

As your code is structured the canvas widget is being passed to the method as an 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 not use the anonymous function ( lambda ), you would have to restructure the code so that the widget stays 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 being altered is because the code was not cleaning the drawing area ( delete() ), basically one circle was getting over the other.

    
31.08.2018 / 16:40