Cannot make default value display for for ttk entry widget using the textvariable parameter

StackOverflow https://stackoverflow.com/questions/23519740

  •  17-07-2023
  •  | 
  •  

Pergunta

Ok, I made it work by changing all the references to the stringvar "commentEntryVar" to "self.commentEntryVar" inside the def initUI function.

I'm not exactly sure why this is necessary (or if making all the references self.commentEntryVar was necessary). Would be pleased if someone can explain why this solved the issue.

self.commentEntryVar = tk.StringVar()
self.commentEntryVar.set("default text")
print "commentEntryVar"
print self.commentEntryVar.get()
commentEntryWidget = ttk.Entry(workoutParametersFrame, textvariable=self.commentEntryVar)
commentEntryWidget.grid(row=6, column=1)

========================================= (THE ORIGINAL QUESTION)

Trying to use the "textvariable" method to set default text for a ttk entry widget. It seems like I'm correctly setting the value of the tk.StringVar, but it is not affecting the window display -- the 'set comment' field remains blank.

commentEntryVar = tk.StringVar()
commentEntryVar.set("default text")

print "commentEntryVar"
print commentEntryVar.get()

commentEntryWidget = ttk.Entry(workoutParametersFrame, textvariable=commentEntryVar)
commentEntryWidget.grid(row=6, column=1)

Shows the

Foi útil?

Solução

If I understand your code, you are doing everything correctly syntactically. If the value is appearing blank on the screen, the only explanation is that commentEntryVar is a local variable that is being garbage-collected after the widget is created but before the window appears.

If it is a local variable, when the function exits the variable will be destroyed and thus the default value will be thrown away. For example, this minimal program illustrates the effect you're seeing since it is using a local variable:

import Tkinter as tk
import ttk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        workoutParametersFrame = tk.Frame(self)
        workoutParametersFrame.pack(fill="both", expand=True);

        # start code from the question
        commentEntryVar = tk.StringVar()
        commentEntryVar.set("default text")

        print "commentEntryVar"
        print commentEntryVar.get()

        commentEntryWidget = ttk.Entry(workoutParametersFrame, 
                                       textvariable=commentEntryVar)
        commentEntryWidget.grid(row=6, column=1)
        # end code from the question

if __name__ == "__main__":
    root = tk.Tk()
    app = Example(root)
    app.pack(fill="both", expand=True)
    app.mainloop()

The fix is to keep a reference to the StringVar so that it is not garbage collected. In this code we're using a class so we can store a reference in a class variable. If you are not using classes and objects you'll need to store it in a global variable.

For example, if you change commentEntryVar to self.commentEntryVar, the problem goes away because the object holds a persistent reference:

...
self.commentEntryVar = tk.StringVar()
...
commentEntryWidget = ttk.Entry(..., textvariable=self.commentEntryVar)
...

Outras dicas

Make sure you keep the reference of the StringVar object.

For example, try following example with / without del commentEntryWidget statement.

try:
    import Tkinter as tk
    import ttk
except ImportError:
    import tkinter as tk
    from tkinter import ttk

root = tk.Tk()
commentEntryVar = tk.StringVar()
commentEntryVar.set("default text")
commentEntryWidget = ttk.Entry(root, textvariable=commentEntryVar)
commentEntryWidget.grid(row=6, column=1)
# del commentEntryWidget
root.mainloop()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top