生成嵌套在wxPython Sizers中的所有sizeritem的列表

2024-09-30 01:21:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法来获取与widget相对应的所有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()返回一个列表(self.sizerItems),其中包含所有不是sizer的sizeritem。对于这个例子,列表中应该有4个元素对应于四个按钮。GetAllChildren()应该递归地沿着sizer树运行,因此vbox首先,然后是{}及其所有子级,然后是{}及其所有子级。

不过,目前我得到的结果是[None,None,None,None]。我意识到try...except是它崩溃的地方,但我不知道如何才能确定某个特定的项目是否是我想要的。关于如何修复这种方法或其他方法有什么建议吗?提前谢谢


Tags: selfrightnoneaddtopbuttonitemleft
2条回答

你要走的路是通往黑暗的!往回走!在

你应该做点什么

def __init__(self):
     ...
     self.widgets = {
       'text_input':textBox,
       'btn1':btn1,
       ....

     }

然后稍后再通过

^{pr2}$

或者

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

我对代码进行了一些修改,使其实际返回的是小部件实例,而不是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次的同一个按钮,我这样做了:

^{pr2}$

您可能还想看看Widget检查工具,它可以直观地显示哪些Widget在哪些sizer中。在

相关问题 更多 >

    热门问题