Wxpython Sizer 位置
我有一个示例应用程序,里面有几个简单的布局,但不知道为什么它们垂直居中显示,这不是我想要的(见附件)。我希望wxchoice布局能固定在窗口的顶部,而不是在中间,即使我调整窗口大小,它也应该保持在那个位置,但我就是找不到解决办法。
import wx
class Mywin(wx.Frame):
def __init__(self, parent, id, title):
super(Mywin, self).__init__(parent, title=title)
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
nm = wx.StaticBox(self.panel, -1, 'Drop List:')
nmSizer = wx.StaticBoxSizer(nm, wx.VERTICAL)
self.workflowList = ["choice 1", "choice 2"]
nmbox = wx.BoxSizer(wx.HORIZONTAL)
self.workflowChoice = wx.Choice(self.panel, choices=self.workflowList)
self.vbox.Add(nmSizer, 0, wx.ALL | wx.EXPAND, 0)
nmbox.Add(self.workflowChoice, 0, wx.ALL, 5)
nmSizer.Add(nmbox, 0, wx.ALL, 5)
self.btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.buttonGo = wx.Button(self.panel, -1, "Go")
self.buttonClose = wx.Button(self.panel, -1, "Quit")
self.btnSizer.Add(self.buttonGo, 0, wx.ALL, 5)
self.btnSizer.Add(self.buttonClose, 0, wx.ALL, 5)
self.vbox.Add(nmSizer, 0, wx.ALL | wx.CENTER | wx.TOP, 5)
self.vbox.Add(self.btnSizer, 0, wx.ALL | wx.CENTER, 5)
self.panel.SetSizer(self.vbox)
self.panel.Fit()
self.Show()
app = wx.App()
Mywin(None, -1, 'Test App ')
app.MainLoop()
2 个回答
0
首先,你的程序中的下拉列表位置奇怪地在切换。这是因为你把 nmSizer 添加了两次到 self.vbox。我把第一次的“添加”注释掉了,奇怪的行为就消失了。
接下来,关于如何让项目保持在窗口顶部的问题:
wxPython 使用 布局管理器的比例属性 来实现这个功能。
比例值高的布局管理器会把比例值低的布局管理器推到一边,具体推到上、下、左、右,取决于它们被添加到的布局管理器类型。
在你的代码中,我给 self.vbox 里的布局管理器设置了比例值为 1。
self.vbox.Add(nmSizer, 1, wx.ALL | wx.CENTER | wx.TOP, 5) # proportion 1
self.vbox.Add(self.btnSizer, 1, wx.ALL | wx.CENTER, 5) # proportion 1
接下来,我在 self.vbox 中添加了一个叫做 间隔器 的东西,并给它设置了比例值为 10。
self.vbox.Add( ( 0, 0), 10, wx.EXPAND, 5 ) # proportion 10
这个间隔器的比例值 10 会把其他的布局管理器推到顶部。间隔器本身是看不见的,它只是“推”其他的布局管理器到顶部。
调整后的代码:
import wx
class Mywin(wx.Frame):
def __init__(self, parent, id, title):
super(Mywin, self).__init__(parent, title=title)
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
nm = wx.StaticBox(self.panel, -1, 'Drop List:')
nmSizer = wx.StaticBoxSizer(nm, wx.VERTICAL)
self.workflowList = ["choice 1", "choice 2"]
nmbox = wx.BoxSizer(wx.HORIZONTAL)
self.workflowChoice = wx.Choice(self.panel, choices=self.workflowList)
# ADD nmSizer 1st time commented this out
# self.vbox.Add(nmSizer, 0, wx.ALL | wx.EXPAND, 0)
nmbox.Add(self.workflowChoice, 0, wx.ALL, 5)
nmSizer.Add(nmbox, 1, wx.ALL, 5) # proportion 1
self.btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.buttonGo = wx.Button(self.panel, -1, "Go")
self.buttonClose = wx.Button(self.panel, -1, "Quit")
self.btnSizer.Add(self.buttonGo, 0, wx.ALL, 5)
self.btnSizer.Add(self.buttonClose, 0, wx.ALL, 5)
# ADD nmSizer 2nd time, KEPT THIS ONE
self.vbox.Add(nmSizer, 1, wx.ALL | wx.CENTER | wx.TOP, 5) # proportion 1
self.vbox.Add(self.btnSizer, 1, wx.ALL | wx.CENTER, 5) # proportion 1
# add spacer
self.vbox.Add( ( 0, 0), 10, wx.EXPAND, 5 ) # proportion 10
self.panel.SetSizer(self.vbox)
self.panel.Fit()
self.Show()
app = wx.App()
Mywin(None, -1, 'Test App ')
app.MainLoop()
使用间隔器来保持物体在顶部。
其他的 wx 对象也可以用作“推器/填充器”。如果你想把面板的剩余部分用作一个文本框,那么给创建的文本框一个高的比例值。
import wx
class Mywin(wx.Frame):
def __init__(self, parent, id, title):
super(Mywin, self).__init__(parent, title=title)
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
nm = wx.StaticBox(self.panel, -1, 'Drop List:')
nmSizer = wx.StaticBoxSizer(nm, wx.VERTICAL)
self.workflowList = ["choice 1", "choice 2"]
nmbox = wx.BoxSizer(wx.HORIZONTAL)
self.workflowChoice = wx.Choice(self.panel, choices=self.workflowList)
# ADD nmSizer 1st time commented this out
# self.vbox.Add(nmSizer, 0, wx.ALL | wx.EXPAND, 0)
nmbox.Add(self.workflowChoice, 0, wx.ALL, 5)
nmSizer.Add(nmbox, 1, wx.ALL, 5) # proportion 1
self.btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.buttonGo = wx.Button(self.panel, -1, "Go")
self.buttonClose = wx.Button(self.panel, -1, "Quit")
self.btnSizer.Add(self.buttonGo, 0, wx.ALL, 5)
self.btnSizer.Add(self.buttonClose, 0, wx.ALL, 5)
# ADD nmSizer 2nd time, KEPT THISS ONE
self.vbox.Add(nmSizer, 1, wx.ALL | wx.CENTER | wx.TOP, 5) # proportion 1
self.vbox.Add(self.btnSizer, 1, wx.ALL | wx.CENTER, 5) # proportion 1
# add spacer not needed, the following textctrl is used for this
# self.vbox.Add( ( 0, 0), 10, wx.EXPAND, 5 ) # proportion 10
# add text ctrl
self.textctrl_info = wx.TextCtrl(self.panel, wx.ID_ANY,
wx.EmptyString, wx.DefaultPosition,
wx.DefaultSize, wx.TE_MULTILINE)
self.vbox.Add(self.textctrl_info, 25, wx.ALL | wx.EXPAND, 5) # proportion 25
self.panel.SetSizer(self.vbox)
self.panel.Fit()
self.Show()
app = wx.App()
Mywin(None, -1, 'Test App ')
app.MainLoop()
使用文本框来保持物体在顶部。
想把推器填充器放在按钮上面吗?只需改变添加到 self.vbox 的顺序即可。
# ADD nmSizer 2nd time, KEPT THISS ONE
self.vbox.Add(nmSizer, 1, wx.ALL | wx.CENTER | wx.TOP, 5) # proportion 1
# add text ctrl
self.textctrl_info = wx.TextCtrl(self.panel, wx.ID_ANY,
wx.EmptyString, wx.DefaultPosition,
wx.DefaultSize, wx.TE_MULTILINE)
self.vbox.Add(self.textctrl_info, 25, wx.ALL | wx.EXPAND, 5) # proportion 25
self.vbox.Add(self.btnSizer, 1, wx.ALL | wx.CENTER, 5) # proportion 1
0
你正在把一个静态框(StaticBox)添加到一个静态框布局(StaticBoxSizer)中,所以可能会出现一些问题。
可以试试下面这样的做法:
import wx
class Mywin(wx.Frame):
def __init__(self, parent, id, title):
super(Mywin, self).__init__(parent, id=id, title=title)
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
nm = wx.StaticBoxSizer(wx.VERTICAL, self.panel, 'Drop List:')
self.workflowList = ["choice 1", "choice 2"]
self.workflowChoice = wx.Choice(self.panel, choices=self.workflowList)
nm.Add(self.workflowChoice, 0, wx.ALL|wx.EXPAND, 5)
self.vbox.Add(nm, 0, wx.ALL, 5) # Add the box to the sizer
self.btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.buttonGo = wx.Button(self.panel, -1, "Go")
self.buttonClose = wx.Button(self.panel, -1, "Quit")
self.btnSizer.Add(self.buttonGo, 0, wx.ALL, 5)
self.btnSizer.Add(self.buttonClose, 0, wx.ALL, 5)
self.vbox.Add(self.btnSizer, 0, wx.ALL|wx.EXPAND, 0)
self.panel.SetSizer(self.vbox)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.buttonClose.Bind(wx.EVT_BUTTON, self.OnClose)
self.Show()
def OnClose(self, event):
self.Destroy()
app = wx.App()
Mywin(None, -1, 'Test App ')
app.MainLoop()