wx.SplitterWindowをネストさせてみる
wx.SplitterWindowをどんどんネストして分割するクラスが欲しかったので書いてみた。
途中sizerがちゃんと使えてなくて頓挫寸前だった。
BoxSizerの場合
sizer.Add(client, 1, wx.Expand)
を基本として
sizer.Add(client, 0, wx.Expand)
と使い分けるべし。
sizerは便利でよろしいのだが、ちょっとした間違いがあってうまくいかない場合(SetSizerし忘れているとか、wx.Expandの指定がよろしくない)に、はまるポイントがあるような気がする。
# -*- coding: utf-8 -*- # 入れ子になったsplitter import wx class NestSplitter(wx.Panel): """ コンテキストメニュー """ def __init__(self, parent, client, *args, **key): super(NestSplitter, self).__init__(parent, *args, **key) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) self.__init_popup_menu() self.Bind(wx.EVT_CONTEXT_MENU, self.__on_context_menu) self.client_class=client self.__client=self.client_class(self) sizer.Add(self.__client, 1, wx.EXPAND) self.splitter=None def __init_popup_menu(self): """ split vertical horizontal """ self.__popupIDSplit = wx.NewId() self.__popupIDSplitVertical = wx.NewId() self.__popupIDSplitHorizontal= wx.NewId() self.Bind(wx.EVT_MENU, self.__on_split, id=self.__popupIDSplitVertical) self.Bind(wx.EVT_MENU, self.__on_split, id=self.__popupIDSplitHorizontal) def __on_context_menu(self, event): if self.splitter: event.Skip() return menu = wx.Menu() # make a submenu sm = wx.Menu() sm.Append(self.__popupIDSplitVertical, "vertical") sm.Append(self.__popupIDSplitHorizontal, "horizontal") menu.AppendMenu(self.__popupIDSplit, "split", sm) self.PopupMenu(menu) menu.Destroy() def __on_split(self, event): self.__client.Destroy() splitter=wx.SplitterWindow(self) p1=self.__class__(splitter, self.client_class) p2=self.__class__(splitter, self.client_class) if event.GetId()==self.__popupIDSplitVertical: splitter.SplitVertically(p1, p2) else: splitter.SplitHorizontally(p1, p2) self.Bind(wx.EVT_SPLITTER_UNSPLIT, self.__on_unsplit) sizer=self.GetSizer() sizer.Add(splitter, 1, wx.EXPAND) self.SetSizer(sizer) # splitterのサイズを再計算する self.Layout() self.splitter=splitter def __on_unsplit(self, event): window=self.__get_leaf_window(self.splitter) self.client_class=window.client_class self.splitter.Destroy() self.splitter=None self.__client=self.client_class(self) self.GetSizer().Add(self.__client, 1, wx.EXPAND) self.Layout() def __get_leaf_window(self, splitter): window=splitter.GetWindow1() child_splitter=window.splitter if child_splitter: return self.__get_leaf_window(child_splitter) else: return window class MyFrame(wx.Frame): def __init__(self, parent): super(MyFrame, self).__init__(parent) sizer=wx.BoxSizer(wx.VERTICAL) self.splitter=NestSplitter(self, client=wx.Panel) sizer.Add(self.splitter, 1, wx.EXPAND) self.SetSizer(sizer) if __name__ == '__main__': app = wx.PySimpleApp() frame = MyFrame(None) frame.Show() app.MainLoop()