Tkinter: ttk.Label displaying nothing when given StringVar as textvariable, inside a class

Question:

I am trying to use the textvariable attribute of ttk.Label to display & update text according to a given StringVar.

from tkinter import *
from tkinter import ttk

class RenderEvent():
    def __init__(self, root):
        self.root = root
        self.frame = ttk.Frame(self.root, padding="20 20 20 20")
        self.frame.grid(column=0, row=0, sticky=(N, W, E, S))
        
        self.dialogue = StringVar(self.frame, value="Placeholder")
        L = ttk.Label(self.frame, textvariable=self.dialogue)
        L.grid(column=1, row=2, sticky=W)
        self.dialogue.set("some text here")

And for reference, root is passed in from another file which looks like this, and is used to start the application:

from tkinter import *
from tkinter import ttk
from renderevent import RenderEvent

root = Tk()
RenderEvent(root)
root.mainloop()

If I use text instead of textvariable in the Label creation, it displays a static string just fine. However, once it is set to textvariable (as shown above), nothing will be displayed at all.

I have tried the same with giving the StringVar() no parameters at all in initialization, or passing in self.root.

Emulating this code outside of a class seems to work as intended (the text appears and updates along with the textvariable), but I can’t think of why having a class would cause an issue like this.

Asked By: perihelions

||

Answers:

The reason is that you aren’t keeping a reference to the instance of RenderEvent. Since you don’t save a reference, python’s garbage collector will try to clean it up which causes the variable to be cleaned up as well. The ttk widgets are more sensitive to this than the normal tk widgets.

The simple and arguably best solution is to assign the result of RenderEvent(root) to a variable so that it isn’t affected by python’s memory management.

re = RenderEvent(root)
Answered By: Bryan Oakley
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.