Posts: 4
Threads: 2
Joined: Sep 2020
Sep-02-2020, 08:07 PM
(This post was last modified: May-25-2023, 11:55 AM by Larz60+.)
i am using tkinter to make my dice roller code look more appealing. i have gotten tkinter to display a roll button that works on the shell but in the same tkinter window it displays one value under roll and wonbt change that number when i click roll. how do i get it to change the number every time i click roll. im stumped
import tkinter as tk
import random
die_1 = random. randint(1,6)
die_2 = random. randint(1,6)
total = float(die_1) + float(die_2)
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets()
def create_widgets(self):
self.button = tk.Button(self)
self.button["text"] = "Roll"
self.button["command"] = self.roll
self.button.pack(side="top")
self.result = tk.Label(self)
self.result["text"] = total
self.result.pack(side="bottom")
def roll(self):
die_1 = random. randint(1,6)
die_2 = random. randint(1,6)
total = float(die_1) + float(die_2)
print(int(total))
root = tk.Tk()
app = Application(master=root)
app.mainloop()
Larz60+ write May-25-2023, 11:55 AM:Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
I fixed your code this time. Please use BBCode tags on future posts.
Posts: 6,202
Threads: 16
Joined: Feb 2020
I think you are missing an opportunity. Buttons can display images, like the face of a die. Why not make a die that you roll by click it and then change the image to reflect the value of the roll.
Posts: 4
Threads: 2
Joined: Sep 2020
(Sep-02-2020, 08:12 PM)deanhystad Wrote: I think you are missing an opportunity. Buttons can display images, like the face of a die. Why not make a die that you roll by click it and then change the image to reflect the value of the roll.
not to be rude but
i would appreciate not being told that i could be doing something not related to my question differently, i may do it in the future but i just want to know how to get past a specific problem
Posts: 6,202
Threads: 16
Joined: Feb 2020
Sep-02-2020, 10:54 PM
(This post was last modified: Sep-02-2020, 10:54 PM by deanhystad.)
Look at tkinter StringVar (or IntVar) for the label. After reading about that the answer should be obvious.
Why are you doing the float conversion and then later the conversion back to int? die 1 and die2 are ints. Can't you add ints?
die_1 = random. randint(1,6)
die_2 = random. randint(1,6)
total = float(die_1) + float(die_2)
print(int(total)) And why does this code appear twice? Why is there die rolling code at the top of the program? A leftover perhaps?
Posts: 4
Threads: 2
Joined: Sep 2020
(Sep-02-2020, 10:54 PM)deanhystad Wrote: Look at tkinter StringVar (or IntVar) for the label. After reading about that the answer should be obvious.
Why are you doing the float conversion and then later the conversion back to int? die 1 and die2 are ints. Can't you add ints?
die_1 = random. randint(1,6)
die_2 = random. randint(1,6)
total = float(die_1) + float(die_2)
print(int(total)) And why does this code appear twice? Why is there die rolling code at the top of the program? A leftover perhaps? i am still very confused, can you just tell me what i should do yo my code to make it work
Posts: 1
Threads: 0
Joined: May 2023
May-25-2023, 10:25 AM
(This post was last modified: May-25-2023, 10:36 AM by gnezdavrukavah.)
I stumbled upon this thread from three years ago, and it seems like you were trying to make your dice roller code more appealing using Tkinter. Nice choice!
In your current code, it looks like the total variable is defined outside the roll function, which means it won't update dynamically. To fix this, you'll want to move the lines where you roll the dice and calculate the total inside the roll function itself. That way, each time you click the roll button, the values will be freshly generated.
To update the displayed number, you can use the configure method on the self.result label. Within the roll function, add self.result.configure(text=total) to ensure the label reflects the newly rolled total.
Oh, and by the way, if you're looking for some inspiration or additional guidance, you can always check out FlipSimu's dice roller. They have a fantastic tool that might provide some useful insights.
Posts: 2,016
Threads: 9
Joined: May 2017
Refactoring service ...
import random
import tkinter as tk
def roll_dice(n):
return tuple(random.randint(1, 6) for _ in range(n))
# inheritance, so the instance of Application is a Frame
class Application(tk.Frame):
def __init__(self, master=None):
# calling super to initialize the Frame
# so __init__ is called on tk.Frame
super().__init__(master)
# 3 IntVars, where value is initialized as empty str
# the first argument is the master, in this case the frame instance
self.total = tk.IntVar(self, "")
self.left_dice = tk.IntVar(self, "")
self.right_dice = tk.IntVar(self, "")
self.create_widgets()
def create_widgets(self):
descriptions = ("Total:", "Dice 1:", "Dice 2:")
variables = (self.total, self.left_dice, self.right_dice)
# zip returns a zip_iterator, which yields tuples
# enumerate takes this tuples and yields index, tuple
# enumerate starts by default with 0 and counts 1 up per element
# to unpack this structure, parenthesis are used
for row, (text, variable) in enumerate(zip(descriptions, variables)):
# no references required yet
# variable sets the text of Label
tk.Label(self, text=text).grid(row=row, column=0)
tk.Label(self, textvariable=variable).grid(row=row, column=1)
# the names row, text and variable
# do not disappear
# row is the last row from for-loop
# adding 1 to it for the next row
row += 1
tk.Button(self, text="Roll", command=self.roll).grid(row=row, column=0)
tk.Button(self, text="Quit", command=self.master.destroy).grid(
row=row, column=1
)
def roll(self):
# roll_dice(2) returns a tuple with two integers
dices = roll_dice(2)
# set the variables, which affects the text on the labels
self.left_dice.set(dices[0])
self.right_dice.set(dices[1])
# sum(dices) -> total
self.total.set(sum(dices))
if __name__ == "__main__":
# this branch is only executed, if you run this program directly
# is this module is imported, this branch does not run
# this makes it possible to reuse the class in other modules
root = tk.Tk()
app = Application(master=root)
# if the Frame is inside a grid, you can't use pack()
# I removed this from the __init__ method
# so you have to call pack/grid on the instance
app.pack()
# instead of indirection, the Tk instance
# is directly used to run the mainloop
root.mainloop()
# before
# app.mainloop()
|