Python Forum

Full Version: Need tkinter help with clicking buttons
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
In the code below I have images of 3 dice (1,2,3) randomly selected and I have the on_click method in place to change the background to red for that die whenever the button for that die is clicked. However, I also want to print the value of that die when it is clicked. For example if 2 is clicked I want to print 2. What is happening when I click on one die it prints the value of all 3 dice randomly selected. So if the 3 random dice selected were 2,3,1 and I click on 2 it prints [[2], [3], [1]] instead of just 2. What do I need to change in my on_click method to fix this?
import random
from tkinter import *
from PIL import ImageTk, Image
import tkinter as tk
from tkinter import messagebox
from tkinter import simpledialog
from tkinter.messagebox import showinfo

root = Tk()


def on_click(event):
    event.widget.config(bg='red')

    buttons = [btn1, btn2, btn3]

    diceclicked = []
    for b in buttons:
        diceclicked.append([value for (key, value) in r.items() if b.cget('image') == key])
    print(diceclicked)

global dice1
dice1 = ImageTk.PhotoImage(Image.open("C:\\Users\\Dan\\Desktop\\Alea_1.png"))

global dice2
dice2 = ImageTk.PhotoImage(Image.open("C:\\Users\\Dan\\Desktop\\Alea_2.png"))

global dice3
dice3 = ImageTk.PhotoImage(Image.open("C:\\Users\\Dan\\Desktop\\Alea_3.png"))


r = {'pyimage1':1,'pyimage2':2,'pyimage3':3}

dice = [dice1,dice2,dice3]

rdice = random.choice(dice)
rdice2 = random.choice(dice)
rdice3 = random.choice(dice)


btn1 = Button(root, image=rdice)
btn1.pack()
btn1.bind('<Button-1>', on_click)

btn2 = Button(root,image=rdice2)
btn2.pack()
btn2.bind('<Button-1>', on_click)

btn3 = Button(root,image=rdice3)
btn3.pack()
btn3.bind('<Button-1>',on_click)

root.mainloop()
for buttons use:
def on_click(btn_no):
...

btn1 = Button(root, image=rdice, command=lambda b=1: on_click(b))
btn1.pack()
btn1 = Button(root, image=rdice2, command=lambda b=2: on_click(b))
btn2.pack()
btn1 = Button(root, image=rdice3, command=lambda b=3: on_click(b))
btn3.pack()
get rid of the globals
don't use absolute paths for images
Your other option is to use functools module and partial
import tkinter as tk
from functools import partial
class Yahtzee(tk.Frame):
    def __init__(self, parent=None):
        ....
    def make_dice(self):
        for pic in picture_list:
            btn=tk.Button(parent, image= pic, command= partial(when_clicked,arguments)
            btn.pack(side=left)
            ......
    def when_clicked(*args):
        ...
            
pretty sure I gave you a class template on your last post, search saving your photo images so they won't get garbage collected, Start making lists, use loops, zip list into dictionaries. Lists are static they won't change position. refract and simplify.