tkinter入口上的StringVar工作正常。ttk上的StringVar。条目失败

tkinter入口上的StringVar工作正常。ttk上的StringVar。条目失败,tkinter,Tkinter,下面的代码将两个tkinter输入字段打包到根tk窗口中。显示的文本通过StringVar设置。创建这两个字段的函数相同,只是一个创建tkinter.Entry对象,另一个创建tkinter.ttk.Entry对象 根据希普曼的文本,tkinter.Entry和tkinter.ttk.Entry都有textvariable选项。它们都为StringVar引用相同的.get()和.set()方法。我找不到任何东西表明ttk.Entry类需要单独处理 为什么ttk.Entry无法显示文本 (MS

下面的代码将两个tkinter输入字段打包到根tk窗口中。显示的文本通过
StringVar
设置。创建这两个字段的函数相同,只是一个创建
tkinter.Entry
对象,另一个创建
tkinter.ttk.Entry
对象

根据希普曼的文本,
tkinter.Entry
tkinter.ttk.Entry
都有
textvariable
选项。它们都为
StringVar
引用相同的
.get()
.set()
方法。我找不到任何东西表明
ttk.Entry
类需要单独处理

为什么
ttk.Entry
无法显示文本

(MS Windows 7上的Python 3.5.1)


由于实现上的差异,小部件的ttk版本容易对变量进行垃圾收集。如果保持对变量的持久引用,代码将正常工作。例如,如果在
label_2
中添加
global var_text
,它将起作用

就个人而言,我认为将
StringVar
Entry
小部件一起使用没有任何价值,除非您依赖于类的一些特殊功能,例如变量跟踪,或者将多个小部件连接到同一个变量

注意:在这些函数中调用
update\u idletasks
完全没有意义。这是双重事实,因为您在调用
pack
之前调用它。也就是说,在调用
pack
grid
place
之前,不会将任何任务添加到此特定小部件的空闲队列中
update_idletask
只会影响已添加到屏幕但尚未绘制的小部件


虽然你认为它没有副作用,但它确实有。调用
update\u idletasks
刷新所有空闲任务,而不仅仅是在此函数中创建的任务。这就是说,它是无害的,因为它所做的只是导致屏幕刷新,不管怎样,只要调用mainloop,屏幕就会刷新

我想知道还有多少人落入了这样的陷阱:认为StringVar对象成为父窗口小部件的一部分,因此会增加其引用计数。
import tkinter
import tkinter.ttk


def label_2(root):
    label = tkinter.ttk.Entry(root)
    var_text = tkinter.StringVar(name='StringVar 2')
    label.config(textvariable=var_text)
    var_text.set('variable label 2')
    root.update_idletasks()  # Shipman recommended precaution has no effect here
    print(var_text, var_text.get(), label.get())
    label.pack()


def label_3(root):
    label = tkinter.Entry(root)
    var_text = tkinter.StringVar(name='StringVar 3')
    label.config(textvariable=var_text)
    var_text.set('variable label 3')
    root.update_idletasks()  # Shipman recommended precaution has no effect here
    print(var_text, var_text.get(), label.get())
    label.pack()


if __name__ == '__main__':
    root = tkinter.Tk()
    label_2(root)
    label_3(root)
    root.mainloop()