2011-08-26 74 views
0

我有一個從xml文件中讀取的選項列表。在列表中有代碼名稱,項目關係,子代號等信息...根據字典和列表動態生成pygtk菜單

我使用以下函數生成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) 

然後對於每個類型(Type可在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

回答

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']

+0

感謝那些做到了! –