wxPython:如何使 sizer 完全填充其父级

wxPython: How to make sizer fill its parent entirely

我有一个问题,BoxSizer 没有填充它的父项。

在上面的屏幕截图中,我指的是包含黄色和紫色面板的 sizer。我希望此 sizer 和面板填充 Main 选项卡中的整个面板。

我发现实现此目的的唯一方法是 SetMinSize() 在 sizer 上设置一些大值。我无法将它设置为面板的实际大小,因为面板上的 GetSize() returns 非常小,绝对不是实际值。

相关代码如下:

import wx


class App(wx.Frame):
    """Main app window wrapping around everything else.
    """

    def __init__(self):
        super(App, self).__init__(None, title='TSP Visual', size=(1200, 900))
        self.init_ui()
        self.Centre()
        self.Show()

    def init_ui(self):
        # Menubar
        menu_bar = wx.MenuBar()
        file_menu = wx.Menu()
        exit_mi = file_menu.Append(wx.ID_EXIT, 'Exit', 'Exit application')
        menu_bar.Append(file_menu, 'File')
        self.SetMenuBar(menu_bar)
        # Main layout
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        # Title
        title = wx.StaticText(panel, label='No instance loaded')
        title_font = wx.Font(wx.FontInfo(18))
        title.SetFont(title_font)
        title.SetMinSize(title.GetTextExtent(title.Label))
        sizer.Add(title, 0, wx.EXPAND | wx.ALL, 10)
        # Tabs
        notebook = wx.Notebook(panel)
        main_tab = MainTab(notebook)
        stats_tab = StatsTab(notebook)
        notebook.AddPage(main_tab, 'Main')
        notebook.AddPage(stats_tab, 'Stats')
        sizer.Add(notebook, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)

        panel.SetSizerAndFit(sizer)
        # Event bindings
        self.Bind(wx.EVT_MENU, lambda e: self.Close(), exit_mi)


class MainTab(wx.Panel):
    """Main tab of the app, solver controls and tsp view.
    """

    def __init__(self, parent):
        super(MainTab, self).__init__(parent)
        self.init_ui()

    def init_ui(self):
        # Panel sizer
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        # Solver controls and TSP view
        controls = SolverControls(self)
        controls.SetBackgroundColour('yellow')
        tsp_view = TSPView(self)
        tsp_view.SetBackgroundColour('purple')
        sizer.Add(controls, 1, wx.EXPAND)
        sizer.Add(tsp_view, 1, wx.EXPAND)
        self.SetSizerAndFit(sizer)


class StatsTab(wx.Panel):
    """Second tab, graphs and statistics
    """

    def __init__(self, parent):
        super(StatsTab, self).__init__(parent)
        self.init_ui()

    def init_ui(self):
        pass


class TSPView(wx.Panel):

    def __init__(self, parent):
        super(TSPView, self).__init__(parent)
        self.init_ui()

    def init_ui(self):
        self.SetBackgroundColour('white')


class SolverControls(wx.Panel):

    def __init__(self, parent):
        super(SolverControls, self).__init__(parent)
        self.init_ui()

    def init_ui(self):
        sizer = wx.GridBagSizer()
        text = wx.StaticText(self, label='Test text')
        sizer.Add(text, (0, 0), (1, 1), wx.ALL, 5)
        button1 = wx.Button(self, label='Button 1')
        sizer.Add(button1, (1, 0), (1, 1), wx.ALL, 5)
        button2 = wx.Button(self, label='Button 2')
        sizer.Add(button2, (2, 0), (1, 1), wx.ALL, 5)
        self.SetSizer(sizer)


if __name__ == '__main__':
    app = wx.App()
    App()
    app.MainLoop()

编辑: 我更改了我的代码示例,使其自包含且可运行。

您不应在 MainTab.init_ui 中调用 SetSizerAndFit():通过调用此函数,您可以将 MainTab 的大小更改为刚好足以容纳其内容。调整父级 window 的大小后,黄色和紫色面板仍应正确调整大小(如果不这样做,则意味着其他地方还有另一个问题,我错过了),但要使其正常工作一开始,只需使用 SetSizer() 即可。

原来这个问题在某种程度上与 i3wm window 经理有关。由于手动调整 window 的大小解决了这个问题,我想出了一个解决方案,在 Show() 之后我对 window 进行了 SetSize()App__init__() 方法如下所示:

def __init__(self):
    super(App, self).__init__(None, title='TSP Visual')
    self.init_ui()
    self.Show()
    self.SetSize(1200, 900)
    self.Centre()