Установите значение по умолчанию для ttk Combobox

Я использую Python 3.2.1 в Arch Linux x86_64. Это действительно сводит меня с ума: я просто хочу иметь предварительно выбранное значение по умолчанию для 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()

Конечно, в реальной программе я должен использовать функцию, поэтому мне нужно другое решение.


person kynikos    schedule 29.07.2011    source источник


Ответы (3)


Проблема в том, что экземпляр 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()
person Eryk Sun    schedule 29.07.2011
comment
Спасибо, работает отлично! На самом деле я использовал класс в своем приложении, но я использовал локальную переменную для box_value; с self.box_value это помогает ;) - person kynikos; 29.07.2011
comment
Извините, что вмешиваюсь, но когда я импортирую ttk, он не распознает Combobox как опцию или виджет. Любые идеи? - person texasman1979; 15.06.2015
comment
@texasman1979, какую версию Python вы используете и какую ОС? Проверьте ttk.__file__, чтобы убедиться, что это правильный ttk модуль. - person Eryk Sun; 15.06.2015
comment
Можно ли установить текущий элемент по значению? Пример: self.box.current("Dubai") - person Jalkhov; 23.01.2021

Когда ваша функция «combo» завершается, локальная переменная «value» уничтожается. Вам нужна постоянная переменная, такая как глобальная переменная или переменная, которая является свойством класса, чтобы значение не удалялось сборщиком мусора, пока виджет все еще существует.

person Bryan Oakley    schedule 29.07.2011
comment
Спасибо за техническое объяснение ^^ - person kynikos; 30.07.2011

Метод get() можно использовать в вашей функции, чтобы переименовать StringVar и сохранить его под другим именем, чтобы избежать его полной потери из-за сборки мусора.

value = StringVar()

keepvalue = value.get()

затем используйте keepvalue вместо значения:

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

Для меня в поле со списком было показано «А».

person MJ_    schedule 30.09.2017