基于字典和列表动态生成pygtk菜单
我有一个从 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)
I have a list of options that I read from an xml file. In the list there is information like codenames, item relations, child codenames ...
I use the following functions to generate pygtk boxes with the proper buttons in it. My problem is that I have to be able to hide/show those boxes at some points (one example would be self.btn_box_web.show()/hide().
How could I better generate my menu's or access them ?
I first generate a list of server install type and make a box with proper buttons in it
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)
Then for each type (type can be in 2 fields since we have main categories and secondaries) I generate a separate box with the components.
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)
My full code can be found here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有很多代码需要执行,所以我不完全确定我确切地知道你想要做什么。不过,我可以想出几种方法,您可以稍后访问这些动态创建的小部件。
一种方法是使用
widget.set_name()
为每个小部件指定一个名称。然后,您可以稍后获取所有子小部件并迭代它们以查找具有该名称的小部件。如果您有很多小部件,这可能会很慢。使用从配置文件中获取的名称作为键值保存一个 dict() 对象可能会更容易,然后您可以动态访问该对象。即,类似:...等等。
稍后,如果您需要“web”服务器类型按钮,您只需调用
widgets['web']['btn']
That's a lot of code to go through, so I'm not entirely sure that I know exactly what you want to do. I can think of a couple of ways that you can later access these dynamically created widgets, though.
One would be to use
widget.set_name()
to give each widget a name. You could then later get all the child widgets and iterate over them looking for the one with that name. If you have a lot of widgets, this might be slow. It might be easier to just keep adict()
object keyed with the names you get from the config file, which you could then dynamically access later. ie, something like:...and so on.
Later, if you need the "web" server-type button, you would just call
widgets['web']['btn']