Updating Tkinter text with label

Question:

I’m trying to make a GUI version of a drinking game, which involves throwing dice. I ‘throw the dice’ virtually, but want to display the outcome on the screen. I thought using Label() would be most useful, but i’m having trouble updating that text (the throw_text variable) when a new dice throw is done.
Instead of the text updating on the screen, a new text appears below the previous one with the new throw.
I don’t want a cascading stream of text, but just one singular text that updates at the dice being thrown i.e. when the ‘Roll!’ button is pressed.

I’ve seen people do it using the Stringvar(), however i must be doing it wrong as it does not have an effect on the appearance.

from tkinter import *

dim = [900, 600]

root = Tk()
root.geometry(f"{dim[0]}x{dim[1]}")
root.title("Mex")
root.iconbitmap("dice.ico")

lbl = Label(root, font=("Times", 200))

num = ['u2680', 'u2681', 'u2682', 'u2683', 'u2684', 'u2685']
d1 = None
d2 = None

throw_txt = StringVar()


def roll_dice():
    global d1, d2
    d1 = random.choice(num)
    d2 = random.choice(num)
    lbl.config(text=f"{d1}{d2}")
    lbl.pack()
    lbl.place(x=dim[0] / 3.8, y=50)

    print("Throw:", check_throw(convert_symbol()))

    throw_txt = str(check_throw(convert_symbol()))
    txt = Label(root, text=throw_txt)
    txt.pack(side=TOP)


def convert_symbol():
    d1_num = None
    d2_num = None
    for n in num:
        if n == d1:
            d1_num = num.index(n) + 1
        if n == d2:
            d2_num = num.index(n) + 1
    if d2_num > d1_num:
        throw = f"{d2_num}{d1_num}"
    else:
        throw = f"{d1_num}{d2_num}"
    return throw


def check_throw(t):
    num_t = int(t)
    if num_t == 21:
        return "Mex"
    elif num_t % 11 == 0:
        return f"Koning: {int(num_t / 11 * 100)}"
    elif num_t % 31 == 0:
        return "Slok uitdelen"
    else:
        return str(num_t)


roll_btn = Button(root, text="Roll!", width=10, command=roll_dice)
roll_btn.config(font=("Bahnschrift", 20))
roll_btn.pack()
roll_btn.place(x=dim[0] / 2.5, y=25)

roll_btn = Button(root, text="Convert", width=10, command=convert_symbol)
roll_btn.config(font=("Bahnschrift", 20))
roll_btn.pack()
roll_btn.place(x=dim[0] / 2.5, y=500)

root.mainloop()
Asked By: Barco

||

Answers:

You could use the configure attribute instead of storing the text of the Label widget into a separate variable.

Take a quick look at this code:

from tkinter import *
root = Tk()
root.title("my game")

def change_text():
    mylabel.configure(text="You just hit the button!")

mylabel = Label(root, text="Hit the button pls")
mylabel.grid(column=0, row=1, sticky='w')

mybutton = Button(root, text="Click me", command=change_text)
mybutton.grid(column=0, row=2, sticky='w')

root.mainloop()
Answered By: Insertx2k_Dev
when a new dice throw is done. Instead of the text updating on the screen, a new text appears below the previous one with the new throw. I don't want a cascading stream of text,  but just one singular text that updates at the dice being thrown i.e. when the 'Roll!' button is pressed.

Used txt.configure to see updates when new dice throw. You can see updates on label.

Change this:

def roll_dice():
    global d1, d2
    d1 = random.choice(num)
    d2 = random.choice(num)
    lbl.config(text=f"{d1}{d2}")
    lbl.pack()
    lbl.place(x=dim[0] / 3.8, y=50)

    print("Throw:", check_throw(convert_symbol()))

    throw_txt = str(check_throw(convert_symbol()))
    txt = Label(root, text=throw_txt)
    txt.pack(side=TOP)

to:

def roll_dice():
    global d1, d2
    d1 = random.choice(num)
    d2 = random.choice(num)
    lbl.config(text=f"{d1}{d2}")
    lbl.pack()
    lbl.place(x=dim[0] / 3.8, y=50)

    print("Throw:", check_throw(convert_symbol()))

    throw_txt = str(check_throw(convert_symbol()))
    txt.configure(text=throw_txt)

Put the Label widget outside of roll_dice() function.

txt = Label(root)
txt.pack(side=TOP)

Screenshot:

enter image description here

Answered By: toyota Supra
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.