我有我的主程序窗口,我想做一个可折叠的面板。我的意思是,一个与窗口的一侧对齐的面板,带有一个折叠/展开按钮。重要的是,当面板折叠/展开时,其他小部件会相应地改变它们的大小以利用它们所拥有的空间。
我该怎么做呢?
我有我的主程序窗口,我想做一个可折叠的面板。我的意思是,一个与窗口的一侧对齐的面板,带有一个折叠/展开按钮。重要的是,当面板折叠/展开时,其他小部件会相应地改变它们的大小以利用它们所拥有的空间。
我该怎么做呢?
这是使用 wx.SplitterWindow 的一种方法
import wx, wx.calendar
class FoldableWindowContainer(wx.Panel):
def __init__(self, parent, left, right):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.SetSizer(sizer)
self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
left.Reparent(self.splitter)
right.Reparent(self.splitter)
self.left = left
self.right = right
self.splitter.SplitVertically(self.left, self.right)
self.splitter.SetMinimumPaneSize(50)
self.sash_pos = self.splitter.SashPosition
sizer.Add(self.splitter, 1, wx.EXPAND)
fold_button = wx.Button(self, size=(10, -1))
fold_button.Bind(wx.EVT_BUTTON, self.On_FoldToggle)
sizer.Add(fold_button, 0, wx.EXPAND)
def On_FoldToggle(self, event):
if self.splitter.IsSplit():
self.sash_pos = self.splitter.SashPosition
self.splitter.Unsplit()
else:
self.splitter.SplitVertically(self.left, self.right, self.sash_pos)
class FoldTest(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
left = wx.Panel(self, style=wx.BORDER_SUNKEN)
right = wx.Panel(self, style=wx.BORDER_SUNKEN)
left_sizer = wx.BoxSizer(wx.VERTICAL)
left.SetSizer(left_sizer)
left_sizer.Add(wx.calendar.CalendarCtrl(left), 1, wx.EXPAND | wx.ALL, 5)
left_sizer.Add(wx.Button(left, label="Act"), 0, wx.EXPAND | wx.ALL, 5)
right_sizer = wx.BoxSizer(wx.VERTICAL)
right.SetSizer(right_sizer)
right_sizer.Add(
wx.StaticText(right, label="Fold panel", style=wx.BORDER_RAISED),
1, wx.EXPAND | wx.ALL, 5
)
FoldableWindowContainer(self, left, right)
app = wx.PySimpleApp()
app.TopWindow = FoldTest()
app.TopWindow.Show()
app.MainLoop()
另外,请查看 wxPython 演示中的 wx.CollapsiblePane。
如果您正确创建层次结构,wxPython(以及 Swing 和其他)的布局管理器应该能够为您执行此操作。让我们假设它绑定到右侧,因此:
+-----------------------------+
|+----------------+ +--------+|
|| | | This is||
|| | | your ||
|| Other stuff | | panel ||
|| | +--------+|
|| | +--------+|
|| | | Another||
|| | | panel ||
|+----------------+ +--------+|
+-----------------------------+
如果您的布局正确,您将拥有一个包含两列的顶级布局,一列用于其他内容,另一列用于右侧容器。
该容器将拥有自己的布局管理器,其中包含两行,一排用于顶部面板,一排用于底部。
这样,当您将顶部面板(您的可折叠面板)调整为更短(折叠)或更高(展开)时,布局管理器应该扩展或收缩底部面板以适应。
显然,您可以使用更复杂的布局管理器,我选择了最简单的布局管理器来说明如何做到这一点,而不会使讨论与列/行跨度和锚点等混淆。您还可以通过反转窗口管理器(水平 <-> 垂直)来更改折叠方向。
Toni Ruža 的原始示例,稍作修改以在 4.0/Phoenix 下工作。非常好的工作示例,谢谢托尼!
import wx
import wx.adv
class FoldableWindowContainer(wx.Panel):
def __init__(self, parent, left, right):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.SetSizer(sizer)
self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
left.Reparent(self.splitter)
right.Reparent(self.splitter)
self.left = left
self.right = right
self.splitter.SplitVertically(self.left, self.right)
self.splitter.SetMinimumPaneSize(50)
self.sash_pos = self.splitter.GetSashPosition()
sizer.Add(self.splitter, 1, wx.EXPAND)
fold_button = wx.Button(self, size=(10, -1))
fold_button.Bind(wx.EVT_BUTTON, self.On_FoldToggle)
sizer.Add(fold_button, 0, wx.EXPAND)
def On_FoldToggle(self, event):
if self.splitter.IsSplit():
self.sash_pos = self.splitter.GetSashPosition()
self.splitter.Unsplit()
else:
self.splitter.SplitVertically(self.left, self.right, self.sash_pos)
class FoldTest(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
left = wx.Panel(self, style=wx.BORDER_SUNKEN)
right = wx.Panel(self, style=wx.BORDER_SUNKEN)
left_sizer = wx.BoxSizer(wx.VERTICAL)
left.SetSizer(left_sizer)
left_sizer.Add(wx.adv.CalendarCtrl(left), 1, wx.EXPAND | wx.ALL, 5)
# left_sizer.Add(wx.Button(left, label="Act"), 0, wx.EXPAND | wx.ALL, 5) # uncommented as unbound
right_sizer = wx.BoxSizer(wx.VERTICAL)
right.SetSizer(right_sizer)
right_sizer.Add(wx.StaticText(right, label="Fold this panel using the thin vertical button on the right"),
1, wx.EXPAND | wx.ALL, 5)
FoldableWindowContainer(self, left, right)
if __name__ == '__main__':
app = wx.App()
ex = FoldTest()
ex.Show()
app.MainLoop()