生成嵌套在wxPython Sizer中的所有sizerItem的列表

时间:2013-12-04 19:49:47

标签: python python-2.7 wxpython

我正在寻找一种方法来获取与小部件相对应的所有sizerItems的列表。为了演示,我创建了以下示例:

import wx
from wx.lib.scrolledpanel import ScrolledPanel 

class Tester(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Window")
        self.panel = ScrolledPanel(parent=self, id=-1)
        self.panel.SetupScrolling()
        self.sizerItems = []

        Btn1 = wx.Button(self.panel, -1, "I'm a Button!") 
        Btn2 = wx.Button(self.panel, -1, "Me Too!") 
        Btn3 = wx.Button(self.panel, -1, "Hey! Quiet up there!") 
        Btn4 = wx.Button(self.panel, -1, "Jeez Frank, relax") 


        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)

        hbox1.Add(Btn1, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        hbox1.Add(Btn2, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        hbox2.Add(Btn3, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        hbox2.Add(Btn4, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)

        vbox.Add(hbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=25)
        vbox.Add(hbox2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=25)

        self.panel.SetSizer(vbox)
        self.panel.Layout()

        self.GetAllChildren(self.panel.GetSizer())
        print self.sizerItems


    def GetAllChildren(self, item):
        try:
            for sizerItem in item.GetChildren():
                self.GetAllChildren(sizerItem)
        except:
            try: 
                item.GetSizer()
                self.GetAllChildren(item.GetSizer())
            except:
                self.sizerItems.append(item)
                return


app = wx.PySimpleApp()
Tester().Show()
app.MainLoop()

此代码使用4个按钮创建GUI。我希望GetAllChildren()返回所有不是sizer的sizerItem的列表(self.sizerItems)。对于此示例,列表中应该有4个元素对应于这四个按钮。 GetAllChildren()应该以递归方式向下运行sizer树,首先是vbox,然后是hbox1及其所有子项,然后是hbox2及其所有子项。

目前,我得到[None,None,None,None]作为结果。我意识到try...except正在打破它,但我不知道如何确定某个特定项目是否符合我的要求。有关如何解决此方法或替代方法的任何建议?提前致谢

2 个答案:

答案 0 :(得分:2)

我稍微使用了代码并对其进行了更改,以便它实际返回了widget实例而不是sizerItem实例:

import wx
from wx.lib.scrolledpanel import ScrolledPanel 

class Tester(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Window")
        self.panel = ScrolledPanel(parent=self, id=-1)
        self.panel.SetupScrolling()
        self.sizerItems = []

        Btn1 = wx.Button(self.panel, -1, "I'm a Button!") 
        Btn2 = wx.Button(self.panel, -1, "Me Too!") 
        Btn3 = wx.Button(self.panel, -1, "Hey! Quiet up there!") 
        Btn4 = wx.Button(self.panel, -1, "Jeez Frank, relax") 


        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)

        hbox1.Add(Btn1, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        hbox1.Add(Btn2, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        hbox2.Add(Btn3, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        hbox2.Add(Btn4, flag=wx.LEFT|wx.RIGHT|wx.TOP, border=10)

        vbox.Add(hbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=25)
        vbox.Add(hbox2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=25)

        self.panel.SetSizer(vbox)
        self.panel.Layout()

        self.GetAllChildren(self.panel.GetSizer())
        print self.sizerItems

    def GetAllChildren(self, item):
        for sizerItem in item.GetChildren():
            widget = sizerItem.GetWindow()
            if not widget:
                # then it's probably a sizer
                sizer = sizerItem.GetSizer()
                if isinstance(sizer, wx.Sizer):
                    self.GetAllChildren(sizer)
            else:
                self.sizerItems.append(widget)

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    Tester().Show()
    app.MainLoop()

您可以在我的一个旧教程中阅读有关此方法的更多信息:

奇怪的是,这是基于另一个StackOverflow问题:

无论如何,当我运行上面的代码时,我得到了一个包含四个按钮的列表。要检查并确保它们不是相同的按钮添加4次,我这样做了:

for item in self.sizerItems: 
    print item.GetLabel()

您可能还想查看窗口小部件检查工具,它可以直观地显示哪些窗口小部件在哪些大小调整器中。

答案 1 :(得分:1)

你要走的路径会导致黑暗面!回头!

你应该做一些像

这样的事情
def __init__(self):
     ...
     self.widgets = {
       'text_input':textBox,
       'btn1':btn1,
       ....

     }

然后稍后通过

访问它们
 my_instance.widgets['text_input'].GetValue()

def validate(self):
      self.widgets['text_input'].GetValue()