TheCog19
TheCog19

Reputation: 1209

tkinter labels, or "updating variables in a loop"

Relevant stuff: Python 2.7, tkinter.

Alright, so I'm running a simple program that basically generates a random number, and returns a statement as a result. I decided it'd be fun to give it buttons and a display to learn to work with GUIs. Since I had little experience properly using classes, I made it a class as well, I know its not necessary, but its helped my familiarity with classes.

Now onto the issue proper! I can't get the dang label to update, and worse, traceback seems to indicate something wonky is happening.

I've read the relevant documentation on tkinter label, and on StringVar and Set, but I can't figure out what's going wrong. My traceback also gets longer each time the program runs, that is, the first time, I get one "variable changed!", the second, I get two "variable changed!", increasing each time.

The gist of it is, I have no idea why my label isn't updating, and don't know where else to look, I'm sure it something obvious.

Anyway, here's the code:

from random import randint
from Tkinter import *
from sys import exit

class GUI:
    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        self.rooms = Button(frame, text = "All Rooms", fg = "blue",     command=self.allrooms)
        self.rooms.pack(side=LEFT)
    
        self.alsoquit = Button(frame, text = "Quit", fg = "green", command=frame.quit)
        self.alsoquit.pack(side=LEFT)
    
        self.displaytext = StringVar()
        self.displaytext.set("hello")
        self.display = Label(master, text=self.displaytext)
        self.display.pack(side=LEFT)

   def callback(*args):
        print "variable changed!"

   def roomselect(self, random):    
       if random == 1:
            self.displaytext.set("The Chest!")
            self.displaytext.trace("w", self.callback)
        elif random == 2:
            self.displaytext.set("Dark Chest")
            self.displaytext.trace("w", self.callback)
        elif random == 3:
            self.displaytext.set("Hush")
            self.displaytext.trace("w", self.callback)
        else:
            quit()

    def allrooms(self):
        random = randint(1,3)
        self.roomselect(random)
    
 root = Tk()
 app = GUI(root)
 root.mainloop()
 root.destroy()

Upvotes: 1

Views: 1029

Answers (1)

falsetru
falsetru

Reputation: 369004

I can't get the dang label to update,

Specify textvariable, not text when you create Label widget:

self.display = Label(master, textvariable=self.displaytext)

My traceback also gets longer each time the program runs, that is, the first time, I get one "variable changed!", the second, I get two "variable changed!", increasing each time.

because self.displaytext.trace("w", self.callback) is multiple times (allrooms is called every time the button is clicked -> which in turn calls roomselect -> which call trace). Call it only once (for example, only in __init__):


from random import randint
from Tkinter import *

class GUI:
    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        self.rooms = Button(frame, text = "All Rooms", fg = "blue",
                            command=self.allrooms)
        self.rooms.pack(side=LEFT)

        self.alsoquit = Button(frame, text = "Quit", fg = "green",
                               command=frame.quit)
        self.alsoquit.pack(side=LEFT)

        self.displaytext = StringVar()
        self.displaytext.set("hello")
        self.displaytext.trace("w", self.callback)  # <---
        self.display = Label(master, textvariable=self.displaytext)  # <---
        self.display.pack(side=LEFT)

    def callback(*args):
        print "variable changed!"

    def roomselect(self, random):    
        if random == 1:
            self.displaytext.set("The Chest!")
        elif random == 2:
            self.displaytext.set("Dark Chest")
        elif random == 3:
            self.displaytext.set("Hush")
        else:
            quit()

    def allrooms(self):
        random = randint(1,3)
        self.roomselect(random)

root = Tk()
app = GUI(root)
root.mainloop()

Upvotes: 1

Related Questions