【问题标题】:How to either sort a wxsizer or remove items without destroying them?如何对 wxsizer 进行排序或删除项目而不破坏它们?
【发布时间】:2013-08-06 11:48:43
【问题描述】:

我有一个 wxpython 网格大小调整器,用于调整位图按钮的子列表大小。我只想创建一次主列表,因为创建这些按钮需要相当长的时间,因此我不想破坏它们。我的想法是以某种方式从sizer 中删除所有按钮,创建一个我希望sizer 包含的按钮的新列表,然后使用sizer 的 AddMany 方法。

如果我不能在不破坏它们的情况下从sizer 中删除按钮,那么有没有办法使用sizer 的 Show 方法来隐藏某些时间,然后让sizer 调整以填补空白?当我把它们藏起来时,我现在能做的就是让它们消失并留下空隙。我需要将下一个项目调整到间隙的位置。

还有没有办法对 grid sizer 的项目列表进行排序?

感谢您提供的任何帮助。

【问题讨论】:

    标签: python user-interface wxpython wxwidgets


    【解决方案1】:

    您无法对 sizer 项目进行就地排序。当然,可以编写自己的函数来执行此操作,但无论如何它都会在后台使用 wxSizer::Detach()Insert()

    【讨论】:

    • 谢谢,这就是我最终要做的。我花了一段时间才意识到,在我分离物品之前我需要隐藏它们,否则它们将保持可见但不受尺寸器的影响。
    【解决方案2】:

    所以我发现 detach 方法就是我要找的!不过,我仍然想知道一种对sizer 的项目列表进行排序的方法,而无需分离所有项目然后重新附加子列表。

    【讨论】:

      【解决方案3】:

      您应该能够在 sizer 的父级上调用 Layout 方法,这将使其重新计算显示的项目。

      【讨论】:

        【解决方案4】:

        让按钮排序有点棘手,但关键是找到要排序的东西。您可以使用按钮标签或按钮名称。我选择了后者。以下代码还演示了如何显示/隐藏按钮:

        import random
        import wx
        
        ########################################################################
        class MyPanel(wx.Panel):
            """"""
        
            #----------------------------------------------------------------------
            def __init__(self, parent):
                """Constructor"""
                wx.Panel.__init__(self, parent)
        
                self.mainSizer = wx.BoxSizer(wx.VERTICAL)
                hSizer = wx.BoxSizer(wx.HORIZONTAL)
        
                for item in range(10):
                    val = random.choice(range(10000,99999))
                    label = "Button %s" % val
                    name = "btn%s" % val
                    btn = wx.Button(self, label=label, name=name)
                    self.mainSizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        
                toggleBtn = wx.Button(self, label="Hide/Show Some Buttons")
                toggleBtn.Bind(wx.EVT_BUTTON, self.onHideShow)
                hSizer.Add(toggleBtn, 0, wx.ALL, 5)
        
                sortBtn = wx.Button(self, label="Sort buttons")
                sortBtn.Bind(wx.EVT_BUTTON, self.onSort)
                hSizer.Add(sortBtn, 0, wx.ALL, 5)
        
                self.mainSizer.Add(hSizer, 0, wx.ALL|wx.CENTER, 5)
                self.SetSizer(self.mainSizer)
        
            #----------------------------------------------------------------------
            def onHideShow(self, event):
                """
                Hide / Show the buttons
                """
                children = self.mainSizer.GetChildren()
                for child in children:
                    widget = child.GetWindow()
                    if isinstance(widget, wx.Button):
                        if widget.IsShown():
                            widget.Hide()
                        else:
                            widget.Show()
        
            #----------------------------------------------------------------------
            def onSort(self, event):
                """
                Sort the buttons
                """
                children = self.mainSizer.GetChildren()
                buttons = []
                for child in children:
                    widget = child.GetWindow()
                    if isinstance(widget, wx.Button):
                        buttons.append(widget)
                        self.mainSizer.Detach(widget)
        
                sortedBtns =  sorted([btn for btn in buttons], key = lambda y: y.GetName())
                # need to prepend them in reverse order to keep the two control buttons on the bottom
                sortedBtns.reverse()
                for btn in sortedBtns:
                    self.mainSizer.Prepend(btn, 0, wx.ALL|wx.CENTER, 5)
                self.Layout()
        
        ########################################################################
        class MyFrame(wx.Frame):
            """"""
        
            #----------------------------------------------------------------------
            def __init__(self):
                """Constructor"""
                wx.Frame.__init__(self, None, title="Test", size=(600,800))
                panel = MyPanel(self)
                self.Show()
        
        if __name__ == "__main__":
            app = wx.App(False)
            frame = MyFrame()
            app.MainLoop()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-05
          • 2012-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多