【问题标题】:wxPython: Hide a widget and remove the leftover spacewxPython:隐藏小部件并删除剩余空间
【发布时间】:2017-07-11 06:55:41
【问题描述】:

我想在 sizer 中隐藏一个小部件,而不是留下空白空间。 我不想删除小部件,因为我想稍后再显示它。

有没有办法隐藏一个小部件并在它移动一个空间后让显示的小部件填充空白点?

下面是一个简单的留出空格的例子:

import wx

class MyPanel(wx.Panel):
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        sizer = wx.GridSizer(1, 3, 0, 0)

        a = wx.Button(self, -1, 'a')
        b = wx.Button(self, -1, 'b')
        c = wx.Button(self, -1, 'c')

        sizer.Add(a, 0, 0, 0)
        sizer.Add(b, 0, 0, 0)
        sizer.Add(c, 0, 0, 0)

        b.Hide()

        self.SetSizer(sizer)

class MyFrame(wx.Frame):
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, parent=None, title="Remove Spaces")
        panel = MyPanel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel, 1, wx.EXPAND)
        self.SetSizer(sizer)
        self.Fit()
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

【问题讨论】:

    标签: python wxpython hide sizer


    【解决方案1】:

    你必须使用wx.GridSizer吗?因为它会给你一个固定的布局,所以即使你隐藏了一个控件,网格仍然会显示那个空间。

    您是否考虑过使用wx.GridBagSizer?试试这个:

    class MyPanel(wx.Panel):
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent)
            self.parent = parent
    
            self.sizer = wx.GridBagSizer()
    
            self.a = wx.Button(self, -1, 'a')
            self.b = wx.Button(self, -1, 'b')
            self.c = wx.Button(self, -1, 'c')
            self.a.Bind(wx.EVT_BUTTON, self.button_clicked)
    
            self.sizer.Add(self.a, pos=(0, 0))
            self.sizer.Add(self.b, pos=(0, 1))
            self.sizer.Add(self.c, pos=(0, 2))
    
            self.SetSizer(self.sizer)
    
        def button_clicked(self, event):
            if self.b.IsShown():
                self.b.Hide()
            else:
                self.b.Show()
            self.parent.Fit()
    

    使用FlexGridSizer

    class MyPanel(wx.Panel):
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent)
            self.parent = parent
    
            self.sizer = wx.FlexGridSizer(1, 3, 0, 0)
    
            self.a = wx.Button(self, -1, 'a')
            self.b = wx.Button(self, -1, 'b')
            self.c = wx.Button(self, -1, 'c')
            self.a.Bind(wx.EVT_BUTTON, self.button_clicked)
    
            self.sizer.Add(self.a)
            self.sizer.Add(self.b)
            self.sizer.Add(self.c)
    
            self.SetSizer(self.sizer)
    
        def button_clicked(self, event):
            if self.b.IsShown():
                self.b.Hide()
            else:
                self.b.Show()
            self.parent.Fit()
    

    【讨论】:

    • 您的示例确实删除了空白空间,但据我所知,这仅适用于 Bag Sizer。有没有办法去除尺寸器类型(网格尺寸器、弹性网格尺寸器、袋子尺寸器等)的空白空间不管
    • 据我所知,GridSizer 是相当静态的。您需要将最后一个按钮读取到第二个位置的 sizer 中。
    • FlexGridSizer 怎么样?
    • 我将您的答案标记为正确,因为您确实展示了一种删除空白空间的方法,即使它没有使用其他尺寸。
    • @Kade 正如你所说,我已经添加了FlexGridSizer