wxPython:折りたたみ可能なパネルウィジェット
-
03-07-2019 - |
質問
メインプログラムウィンドウがあり、折りたたみ可能なパネルを作成したい。私が言いたいのは、折り畳み/展開ボタンを備えた、ウィンドウの側面のいずれかに位置合わせされたパネルです。パネルが折りたたまれたり展開されたりするとき、他のウィジェットはそれに応じてサイズを変更して、スペースを活用することが重要です。
これを行う方法
解決
wx.SplitterWindowを使用する1つの方法
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 ||
|+----------------+ +--------+|
+-----------------------------+
レイアウトが適切に行われている場合、トップレベルのレイアウトには2つの列があります。1つは他のもの用、もう1つは右側のコンテナ用です。
そのコンテナには、上部パネル用と下部用の2つの行を持つ独自のレイアウトマネージャーがあります。
このように、上部パネル(折りたたみ可能なパネル)を短く(折りたたむ)または高く(展開する)にサイズ変更する場合、レイアウトマネージャーは下部パネルを拡大または縮小して収まるようにします。
明らかに、より複雑なレイアウトマネージャーを使用できます。列/行のスパンやアンカーなどで議論を煩雑にすることなく、最も簡単なレイアウトマネージャーを選択して、その方法を説明しました。ウィンドウマネージャーを逆にすることで、折りたたみの方向を変更することもできます(水平<!> lt;-<!> gt;垂直)。
Toni Ru <!>#382; aの元の例で、4.0 / Phoenixで動作するようにわずかに修正されています。非常に素晴らしい作業例、Toniに感謝!
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()