无法通过textvariable参数为ttk输入控件设置默认值显示

-1 投票
2 回答
6609 浏览
提问于 2025-04-18 05:40

好的,我通过把所有提到字符串变量 "commentEntryVar" 的地方改成 "self.commentEntryVar" 来解决了这个问题,都是在 def initUI 函数里面。

我不太明白为什么这样做是必要的(或者说把所有的引用都改成 self.commentEntryVar 是否真的必要)。如果有人能解释一下为什么这样解决了问题,我会很高兴。

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)

========================================= (原问题)

我在尝试使用 "textvariable" 方法来为一个 ttk 输入框设置默认文本。看起来我确实正确地设置了 tk.StringVar 的值,但它并没有影响窗口的显示——'设置评论'的字段还是空的。

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

print "commentEntryVar"
print commentEntryVar.get()

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

显示 '设置评论' 字段是空的,而不是显示默认文本

2 个回答

0

确保你保留了 StringVar 对象的引用。

比如,你可以试试下面的例子,看看加上和不加 del commentEntryWidget 这行代码有什么不同。

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()
4

如果我理解你的代码没错,你的语法是完全正确的。如果屏幕上显示的值是空白的,唯一的解释就是 commentEntryVar 是一个局部变量,它在小部件创建后但在窗口显示之前就被垃圾回收了。

局部变量的意思是,当函数执行完毕后,这个变量就会被销毁,所以它的默认值也会被丢弃。例如,下面这个简单的程序展示了你所看到的效果,因为它使用了一个局部变量:

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()

解决这个问题的方法是保持对 StringVar 的引用,这样它就不会被垃圾回收。在这个代码中,我们使用了一个类,这样我们就可以把引用存储在类的变量里。如果你没有使用类和对象,那你需要把它存储在一个全局变量中。

举个例子,如果你把 commentEntryVar 改成 self.commentEntryVar,问题就解决了,因为这个对象持有一个持久的引用:

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

撰写回答