Обновление OptionMenu из списка

У меня есть OptionMenu в моем графическом интерфейсе, который заполняется списком. Каждый раз, когда пользователь запускает определенный процесс, список обновляется, чтобы отразить это. Есть ли способ обновить OptionMenu на основе списка? Я пробовал self.plotWindow.update() в соответствии с этим вопросом, но безрезультатно. Однако закрытие и повторное открытие окна обновляет OptionMenu, как и следовало ожидать. Соответствующий код:

if self.figNum.get() == 'New Figure...':
    if self.figList[-1] == 'New Figure...':
        self.figList.append(1)
    else:
        self.figList.append(self.figList[-1]+1)
    self.plotWindow.update() #tk.Tk() window
    self.i = self.figList[-1]
else:
    self.i = self.figNum.get()

person wes3449    schedule 09.02.2015    source источник


Ответы (2)


Параметры в OptionMenu не привязаны к списку, из которого они созданы. Поэтому изменение списка не меняет OptionMenu, вам придется обновлять его самостоятельно.

Вы можете сделать это, получив menu OptionMenu и добавив к нему команды. В следующем примере показано, как это сделать (на основе этого ответа).

Он показывает, что, хотя к списку self.options добавляется опция с помощью кнопки «Добавить опцию в список», OptionMenu не изменяется автоматически. Чтобы обновить OptionMenu, вы можете использовать для этого кнопку «Обновить меню опций», которая вызывает self.update_option_menu. Эта функция удаляет все параметры из OptionMenu и вставляет новый для каждого элемента в self.options.

import Tkinter as tk

class App():
    def __init__(self, parent):
        self.parent = parent
        self.options = ['one', 'two', 'three']

        self.om_variable = tk.StringVar(self.parent)
        self.om_variable.set(self.options[0])
        self.om_variable.trace('w', self.option_select)

        self.om = tk.OptionMenu(self.parent, self.om_variable, *self.options)
        self.om.grid(column=0, row=0)

        self.label = tk.Label(self.parent, text='Enter new option')
        self.entry = tk.Entry(self.parent)
        self.button = tk.Button(self.parent, text='Add option to list', command=self.add_option)

        self.label.grid(column=1, row=0)
        self.entry.grid(column=1, row=1)
        self.button.grid(column=1, row=2)

        self.update_button = tk.Button(self.parent, text='Update option menu', command=self.update_option_menu)
        self.update_button.grid(column=0, row=2)

    def update_option_menu(self):
        menu = self.om["menu"]
        menu.delete(0, "end")
        for string in self.options:
            menu.add_command(label=string, 
                             command=lambda value=string: self.om_variable.set(value))

    def add_option(self):
         self.options.append(self.entry.get())
         self.entry.delete(0, 'end')
         print self.options

    def option_select(self, *args):
        print self.om_variable.get()


root = tk.Tk()
App(root)
root.mainloop()
person fhdrsdg    schedule 09.02.2015
comment
Это идеально, спасибо! Я действительно не понимаю, почему это работает (я пытался реализовать это по-другому, и это не удалось), но, тем не менее, это работает, и этого достаточно для меня. - person wes3449; 09.02.2015
comment
Какую часть точно вы не понимаете? Я мог бы попытаться объяснить это еще немного. - person fhdrsdg; 09.02.2015
comment
В основном просто тот факт, что мы добавляем команду вместо строки. (Хотя я думаю, поскольку мы делаем command = lambda, это становится командой, которая ничего не делает). Я имею в виду функцию update_option_menu, все остальное имеет смысл. - person wes3449; 09.02.2015
comment
OptionMenu — это виджет Menu. Чтобы получить доступ к меню OptionMenu, вы используете self.om['menu']. Метод add_command такой же, как и в обычном меню. Записи меню изменяют переменную, связанную с OptionMenu, на значение, которое они представляют. - person fhdrsdg; 09.02.2015

Я считаю, что простым решением для обновления OptionMenu было бы использование функции настройки, встроенной в класс, например:

my_option_menu.configure(window, user_choice, *updated_list)
person Harper Rhett    schedule 02.04.2021