Как я могу динамически заполнить виджет параметров в tkinter в зависимости от выбора из раскрывающегося меню?

моя проблема заключается в следующем: у меня есть несколько файлов, и я сделал раскрывающееся меню с именами, следующее, что мне нужно, это меню параметров, которое можно изменить всякий раз, когда выбрано имя файла, чтобы показать некоторые данные из конкретного файла как вариант. Чтобы было ясно, мой вопрос касается только того, как изменить меню параметров, когда выбран выбор из раскрывающегося списка. Спасибо за любую помощь.


person IordanouGiannis    schedule 12.09.2011    source источник


Ответы (2)


Виджет OptionMenu — это не что иное, как вспомогательный класс, который создает кнопку меню, связанную с меню. Вы можете попасть в это меню через атрибут "menu". Единственная хитрость заключается в том, чтобы знать, что должны делать пункты меню, что является не чем иным, как установкой значения связанной переменной.

Вот пример:

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.om_variable = tk.StringVar(self)

        b1 = tk.Button(self, text="Colors", width=8, command=self.use_colors)
        b2 = tk.Button(self, text="Sizes", width=8, command=self.use_sizes)

        self.om = tk.OptionMenu(self, self.om_variable, ())
        self.om.configure(width=20)
        self.use_colors()

        b1.pack(side="left")
        b2.pack(side="left")
        self.om.pack(side="left", fill="x", expand=True)


    def _reset_option_menu(self, options, index=None):
        '''reset the values in the option menu

        if index is given, set the value of the menu to
        the option at the given index
        '''
        menu = self.om["menu"]
        menu.delete(0, "end")
        for string in options:
            menu.add_command(label=string, 
                             command=lambda value=string:
                                  self.om_variable.set(value))
        if index is not None:
            self.om_variable.set(options[index])

    def use_colors(self):
        '''Switch the option menu to display colors'''
        self._reset_option_menu(["red","orange","green","blue"], 0)

    def use_sizes(self):
        '''Switch the option menu to display sizes'''
        self._reset_option_menu(["x-small", "small", "medium", "large"], 0)

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
person Bryan Oakley    schedule 13.09.2011
comment
Очень хорошее объяснение и очень полезно. Спасибо. - person IordanouGiannis; 13.09.2011
comment
Итак, вы говорите, что для динамического добавления пунктов меню в уже созданное меню вам нужно удалить пункты меню, прежде чем вы сможете создавать новые? - person Brōtsyorfuzthrāx; 21.05.2014
comment
@ user2962794: нет, это не совсем то, о чем я говорю. Нет необходимости удалять элементы, которые там есть. По сути, это просто меню, и у вас есть полный доступ ко всем методам меню. Вы можете вставлять новые элементы, а также удалять или изменять существующие элементы. - person Bryan Oakley; 21.05.2014
comment
Извини. Я понял. У меня была какая-то ошибка или что-то в моем коде, из-за которого элементы динамического меню не отображались (и поэтому я нашел этот вопрос и попросил разъяснений). Он работает так, как я изначально надеялся (я имею в виду, вам не нужно добавлять пункты меню при создании меню). Тем не менее, приятно услышать разъяснения! :) - person Brōtsyorfuzthrāx; 23.05.2014

Поскольку OptionMenu предоставляет параметр команды, я бы предложил сохранить ссылку на уже заданную команду (если она есть) и передать ее новым параметрам следующим образом:

посещаемость, переменные на основе предыдущего ответа

def __init__(self, *args, **kwargs):
    ...
    self.command=kwargs['command']
    ...

def _reset_option_menu(options, index=None):
    ...
    menu.add_command(label=string, 
                     command=lambda:self.command(),
                     value=self.om_variable.set(string))                         
        ...

Надеюсь, это будет полезно, кстати, действительно полезен ответ, данный Брайаном Окли,

person Lino Bossio    schedule 19.12.2014