为ttk Combobox设置默认值

17

我在 Arch Linux x86_64 上使用 Python 3.2.1。 这个问题真的让我发疯了:我只想为 ttk.Combobox 设置一个默认的预选值,一旦我把它放到网格中。以下是我的代码:

from tkinter import Tk, StringVar, ttk

root = Tk()

def combo(parent):
    value = StringVar()
    box = ttk.Combobox(parent, textvariable=value, state='readonly')
    box['values'] = ('A', 'B', 'C')
    box.current(0)
    box.grid(column=0, row=0)

combo(root)

root.mainloop()

绘制一个空的Combobox。有趣的是,如果我不使用函数,它会完美地工作:

from tkinter import Tk, StringVar, ttk

root = Tk()

value = StringVar()
box = ttk.Combobox(root, textvariable=value, state='readonly')
box['values'] = ('A', 'B', 'C')
box.current(0)
box.grid(column=0, row=0)

root.mainloop()

当然,在实际程序中我需要使用一个函数,因此我需要另一种解决方案。

3个回答

44

问题在于 StringVar 实例被垃圾回收了。这是因为你的代码中它是一个局部变量。

一种解决方案是使用类来使你的 StringVar 持久化:

from tkinter import Tk, StringVar, ttk

class Application:

    def __init__(self, parent):
        self.parent = parent
        self.combo()

    def combo(self):
        self.box_value = StringVar()
        self.box = ttk.Combobox(self.parent, textvariable=self.box_value, 
                                state='readonly')
        self.box['values'] = ('A', 'B', 'C')
        self.box.current(0)
        self.box.grid(column=0, row=0)

if __name__ == '__main__':
    root = Tk()
    app = Application(root)
    root.mainloop()

谢谢,它完美地工作了!实际上我在我的应用程序中使用了一个类,但是我在box_value上使用了一个局部变量;使用self.box_value就可以解决问题了 ;) - kynikos
抱歉打扰一下,当我导入ttk时,它不认识“Combobox”作为选项或小部件。有什么想法吗? - texasman1979
@texasman1979,你使用的是哪个版本的Python和哪个操作系统?检查 ttk.__file__ 确保它是正确的 ttk 模块。 - Eryk Sun
可以通过值来设置当前项目吗?例如:self.box.current("迪拜") - Jalkhov

5

当你的函数“combo”退出时,局部变量“value”将被销毁。你需要一个持久的变量,比如全局变量或者是一个类的属性变量,这样在小部件仍然存在时,该值不会被垃圾回收。


感谢您的技术解释 ^^ - kynikos

2

get() 方法可在函数内部使用,将 StringVar 重命名并保存在另一个名称下,以避免通过垃圾回收完全丢失它。

value = StringVar()

keepvalue = value.get()

那么请使用keepvalue而不是value

box = ttk.Combobox(root, textvariable=keepvalue, state='readonly')

对我来说,这在组合框中显示为'A'。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接