@motya88

Как задать значение по умолчанию для всех созданных combobox в Tkinter?

Мне надо сделать форму для выставления соответствия. Ниже я взял свой кусок кода.
def print_all_entries(unique_types, entry, label):
    for name in unique_types:
        print(name + ' --->' + entry[name].get())


def s():
    unique_types = ['1', '2', '3', '4', '5']
    entry = {}
    label = {}
    combo_list = []
    types = ['Соответсвия нет', 'A', 'B', 'C']

    i = 0
    for name in unique_types:
        value = StringVar()
        lb = ttk.Label(root, text=name)
        lb.grid(row=i, column=0)
        label[name] = lb

        combobox = ttk.Combobox(textvariable=value, values=types, width=90, state="readonly")
        combobox.grid(row=i, column=2, padx=10, pady=5)
        combo_list.append(combobox)

        entry[name] = combobox
        i += 1

    for c in combo_list:
        c.current(0)
        print(c.get())

    b = ttk.Button(root, text="Print all", command=lambda: print_all_entries(unique_types, entry, label))
    b.grid(row=i + 1, column=2, padx=10, pady=5)


root = Tk()

s()
root.mainloop()


Почему у меня не заполняется значение по умолчания для последнего 5-го combobox? Как это исправить?
Почему когда я прохожусь по списку combo_list мне печатаются все значения, но при выполнении функции у 5-го combobox если значение не выбрать то пусто?63d78ea5cc2b4740647455.png63d78eac03641658097137.png
  • Вопрос задан
  • 36 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
По итогам ряда экспериментов у меня получилось следующее...

Когда ты ставишь ссылку на переменную Tk (например, экземпляр StringVar) для элемента управления, элемент запоминает внутреннее имя этой переменной (если ты его не задал явно, оно будет иметь вид PY_VAR*), а не хранит ссылку на сам экземпляр класса StringVar. Поэтому переменная умирает, когда значение питоновской переменной value перезаписывается на следующей итерации, что ломает логику работы.
Ты должен сам хранить ссылки на все StringVar на всё время жизни твоего окна. Например, так:
variables = {}

def s():
    unique_types = ['1', '2', '3', '4', '5']
    entry = {}
    label = {}
    combo_list = []
    types = ['Соответсвия нет', 'A', 'B', 'C']

    for row, name in enumerate(unique_types, 0):
        value = StringVar()
        variables[name] = value
        lb = ttk.Label(root, text=name)
        lb.grid(row=row, column=0)
        label[name] = lb

        combobox = ttk.Combobox(root, textvariable=value, values=types, width=90, state="readonly")
        combobox.current(0)
        combobox.grid(row=row, column=2, padx=10, pady=5)
        combo_list.append(combobox)
        entry[name] = combobox

    b = ttk.Button(root, text="Print all", command=lambda: print_all_entries(unique_types, entry, label))
    b.grid(row=row + 1, column=2, padx=10, pady=5)


Одна из причин, почему я обычно советую описывать окно как класс-наследник tkinter.Frame. В конструкторе создаёшь переменные, сохраняешь в поля класса, и они лежат себе. Когда экземпляр класса умрёт, они тоже уничтожатся.
А потом этот экземпляр пакуешь уже в окно верхнего уровня.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Фаст Софт Санкт-Петербург
от 150 000 до 180 000 ₽
Sibdev Красноярск
от 120 000 до 180 000 ₽
Сбер Москва
от 250 000 до 350 000 ₽