Динамически генерировать меню Pygtk на основе словарей и списков - PullRequest
0 голосов
/ 26 августа 2011

У меня есть список опций, которые я читаю из XML-файла.В списке есть такая информация, как кодовые имена, отношения элементов, дочерние кодовые имена ...

Я использую следующие функции для генерации блоков pygtk с соответствующими кнопками в нем.Моя проблема в том, что я должен иметь возможность скрывать / показывать эти поля в некоторых точках (например, self.btn_box_web.show () / hide ().

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

Сначала я создаю список типов установки сервера и создаю прямоугольник с соответствующими кнопками

def build_custom_server(self, server_type_dict, component_dict):
    self.custom_server_box = gtk.VBox(False, 0)
    self.option_box.pack_start(self.custom_server_box, False)
    self.custom_server_box.set_border_width(10)
    self.custom_server_label = gtk.Label("Customize your server instalation:")
    self.custom_server_box.pack_start(self.custom_server_label, True)

    self.type_box = gtk.HBox(True, 0)
    self.custom_server_box.pack_start(self.type_box, False)
    self.type_label = gtk.Label("Server type:")
    self.type_box.pack_start(self.type_label, True)

    for stype in server_type_dict:
        self.btn_name = "self.btn_" + stype
        self.img_name = "self.img_" + stype
        self.label_name = "self.label_" + stype
        self.box_name = "self.btn_box_" + stype

        vars()[self.btn_name] = gtk.ToggleButton()
        vars()[self.box_name] = gtk.VBox(False, 0)
        vars()[self.img_name] = gtk.Image()
        vars()[self.img_name].set_from_file("art/" + stype + ".png")
        vars()[self.label_name] = gtk.Label(server_type_dict[stype])
        vars()[self.box_name].pack_start(vars()[self.img_name], False)
        vars()[self.box_name].pack_end(vars()[self.label_name], False)
        vars()[self.btn_name].add(vars()[self.box_name])
        self.type_box.pack_start(vars()[self.btn_name], True)
        self.load_type(server_type_dict, component_dict, stype)

Затем для каждого типа (тип может быть в 2 полях, так как у нас есть mainкатегории и дополнительные элементы) Я создаю отдельную коробку с компонентами.

def load_type(self, server_type_dict, component_dict, stype):
    self.up_label_name = "self.label_" + stype
    self.up_box_name = "self.btn_box_" + stype
    vars()[self.up_box_name] = gtk.HBox(False, 0)
    vars()[self.up_label_name] = gtk.Label(server_type_dict[stype])
    vars()[self.up_box_name].pack_start(vars()[self.up_label_name], False)

    self.custom_server_box.pack_start(vars()[self.up_box_name], False)
    for compo in component_dict:
        if component_dict[compo][1] == stype:
            self.btn_name = "self.btn_" + compo
            self.img_name = "self.img_" + compo
            self.label_name = "self.label_" + compo
            self.box_name = "self.btn_box_" + compo

            vars()[self.btn_name] = gtk.ToggleButton()
            vars()[self.box_name] = gtk.VBox(False, 0)
            vars()[self.img_name] = gtk.Image()
            vars()[self.img_name].set_from_file("art/" + compo + ".png")
            vars()[self.label_name] = gtk.Label(component_dict[compo][0])
            vars()[self.box_name].pack_start(vars()[self.img_name], False)
            vars()[self.box_name].pack_end(vars()[self.label_name], False)
            vars()[self.btn_name].add(vars()[self.box_name])
            vars()[self.up_box_name].pack_start(vars()[self.btn_name], True)
        elif component_dict[compo][2] == stype:
            self.btn_name = "self.btn_" + compo
            self.img_name = "self.img_" + compo
            self.label_name = "self.label_" + compo
            self.box_name = "self.btn_box_" + compo

            vars()[self.btn_name] = gtk.ToggleButton()
            vars()[self.box_name] = gtk.VBox(False, 0)
            vars()[self.img_name] = gtk.Image()
            vars()[self.img_name].set_from_file("art/" + compo + ".png")
            vars()[self.label_name] = gtk.Label(component_dict[compo][0])
            vars()[self.box_name].pack_start(vars()[self.img_name], False)
            vars()[self.box_name].pack_end(vars()[self.label_name], False)
            vars()[self.btn_name].add(vars()[self.box_name])
            vars()[self.up_box_name].pack_start(vars()[self.btn_name], True)

Мой полный код можно найти здесь

1 Ответ

0 голосов
/ 26 августа 2011

Это большой код, который нужно пройти, поэтому я не совсем уверен, что точно знаю, что вы хотите сделать.Однако я могу подумать о нескольких способах получения доступа к этим динамически созданным виджетам.

Можно использовать widget.set_name(), чтобы дать каждому виджету имя.Позже вы можете получить все дочерние виджеты и перебрать их в поисках одного с таким именем.Если у вас много виджетов, это может быть медленно.Возможно, будет проще просто сохранить объект dict() с именами, полученными из файла конфигурации, к которым вы затем сможете динамически обращаться позже.то есть что-то вроде:

widgets = {}
for stype in server_type_dict:
    widgets[stype] = {}
    widgets[stype]['btn'] = gtk.ToggleButton()
    widgets[stype]['box'] = gtk.VBox(False, 0)
    widgets[stype]['img'] = gtk.Image()
    ...
    self.type_box.pack_start(widgets[stype]['btn'], True)
    self.load_type(server_type_dict, component_dict, stype)

... и т. д.

Позже, если вам понадобится кнопка типа "web" для сервера, вы просто позвоните widgets['web']['btn']

...