如何使 wxpython 小部件跨越两个单元格而不将其他小部件放在一边?

How can I make a wxpython Widget span two cells without pushing other widgets aside?

我正在尝试制作一个包含多个输入字段的表单。在这些字段下面,我想要一个 wxpython Ultimate List Control(对于所有意图和目的,它与 List Control 是一样的)。我的问题是 sizer。为了提供一些背景信息,我的表单如下所示

Name         [TextCtrl]
Blah         [TextCtrl]

ListControl

我希望它看起来像

Name   [TextCtrl]
Blah   [TextCtrl]
ListCtrl (this spans to the end of the row)

我的问题是当我尝试添加列表控件时。我希望列表控件从静态文本拉伸到文本控件,但它会将 TextControl 推过去。有人可以指出我正确的方向吗?我在下面附上了相关代码。

class UserField(wx.Dialog):
def __init__(self, parent):
    wx.Dialog.__init__(self, parent=parent, title="Info", size=(350, 400),
                       style=wx.DEFAULT_FRAME_STYLE)


    self.init_ui()
    self.Center()
    self.ShowModal()

def init_ui(self):
    panel = wx.Panel(self, wx.ID_ANY)
    hbox = wx.BoxSizer(wx.VERTICAL)
    flex_grid = wx.FlexGridSizer(5, 2, 5, 10) # row, col, vgap, hgap


    info_text = wx.StaticText(parent=panel, label="Enter information")
    self.search_button = wx.Button(parent=panel, label="Search")
    self.list_control = UltimateListCtrl(panel,
        agwStyle=wx.LC_REPORT | wx.BORDER_SUNKEN | ULC_HAS_VARIABLE_ROW_HEIGHT, )

    flex_grid.AddMany(
            [
                info_text, self.search_button
            ]
    )
    lbox = wx.BoxSizer(wx.HORIZONTAL)
    lbox.Add(self.list_control
    hbox.Add(flex_grid, wx.EXPAND|wx.ALL)
    hbox.Add(lbox, proportion=1, flag=wx.ALL|wx.EXPAND)
    panel.SetSizer(hbox)

下面是 wx.GridBagSizer 的快速演示。该程序使用一个按钮打开一个简单的框架,该按钮生成一个带有 GridBagSizer 的对话框。您可以根据位置 (pos) 将项目放置在 sizer 中,并可选择允许小部件跨越多行 and/or 列 (span)。

import wx

class Example(wx.Frame):

    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.SetSize((300, 200))
        self.Centre()
        self.Show(True)
        self.InitUI()

    def InitUI(self):    
        panel = wx.Panel(self)
        sizer = wx.BoxSizer()
        btn = wx.Button(panel, label="Spawn Window")
        btn.Bind(wx.EVT_BUTTON, self.spawn_window)
        sizer.Add(btn)
        panel.SetSizerAndFit(sizer)

    def spawn_window(self, evt):
        UserField(self)

    def OnQuit(self, e):
        self.Close()

class UserField(wx.Dialog):

    def __init__(self, parent):
        wx.Dialog.__init__(self, parent=parent, title="Info", size=(350, 400),
                           style=wx.DEFAULT_FRAME_STYLE)
        self.init_ui()
        self.Center()
        self.ShowModal()

    def init_ui(self):
        panel = wx.Panel(self)
        sizer = wx.GridBagSizer(10, 10)
        field1Label = wx.StaticText(panel, label="Field 1")
        field2Label = wx.StaticText(panel, label="Field 2")
        field1Ctrl = wx.TextCtrl(panel)
        field2Ctrl = wx.TextCtrl(panel)
        listCtrl = wx.ListCtrl(panel)
        sizer.Add(field1Label, pos=(0, 0))
        sizer.Add(field2Label, pos=(1, 0))
        sizer.Add(field1Ctrl, pos=(0, 1))
        sizer.Add(field2Ctrl, pos=(1, 1))
        # HERE'S THE IMPORTANT LINE. NOTE THE 'span' ARGUMENT:
        sizer.Add(listCtrl, pos=(2, 0), span=(1, 2), flag=wx.EXPAND)
        panel.SetSizerAndFit(sizer)

if __name__ == '__main__':
    ex = wx.App()
    mainFrame = Example(None)
    ex.MainLoop()