根据字典和列表动态生成pygtk菜单

时间:2011-08-26 04:22:41

标签: python dynamic menu pygtk generator

我有一个从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个字段中),我生成一个单独的包含组件的框。

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)

我的完整代码可以找到here

1 个答案:

答案 0 :(得分:0)

这需要经过很多代码,所以我并不完全确定我确切知道你想要做什么。不过,我可以想到以后可以通过几种方式访问​​这些动态创建的小部件。

一种方法是使用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)

......等等。

稍后,如果您需要“网络”服务器类型按钮,则只需拨打widgets['web']['btn']