How do I layout a 3 pane window using wxPython?
I am trying to find a simple way to layout a 3 pane window using wxPython.
I want to have a tree list in the left pane, then have a right pane that is split into two - with an edit component in the top part and a grid component in the bottom part.
Something along the lines of:
-------------------------------------- | | | | | Edit | | Tree | Control | | Control | | | |----------------------| | | | | | Grid | | | | --------------------------------------
I would like the window to be re-sizable and give the user the ability to change the (relative) size of each of the components within the windows by dragging the borders.
I figure that I need some combination of sizers and/or splitter-window components but can't find a decent example of this kind of window in the documentation or on the web.
Then you have to decide if you want to use a GridSizer or a Splitter and you are done. Below you find both (between Tree and right side is a GridSizer -> resizes automatically). Between Edit and GridCtrl is a Sizer (manual Resize).
one minute work without entering a single line of code:
#!/usr/bin/env python # -*- coding: utf-8 -*- # generated by wxGlade 0.6.3 on Sat Feb 07 10:02:31 2009 import wx import wx.grid # begin wxGlade: extracode # end wxGlade class MyDialog(wx.Dialog): def __init__(self, *args, **kwds): # begin wxGlade: MyDialog.__init__ kwds["style"] = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.THICK_FRAME wx.Dialog.__init__(self, *args, **kwds) self.window_1 = wx.SplitterWindow(self, -1, style=wx.SP_3D|wx.SP_BORDER) self.tree_ctrl_1 = wx.TreeCtrl(self, -1, style=wx.TR_HAS_BUTTONS|wx.TR_LINES_AT_ROOT|wx.TR_DEFAULT_STYLE|wx.SUNKEN_BORDER) self.text_ctrl_1 = wx.TextCtrl(self.window_1, -1, "This is the Edit", style=wx.TE_MULTILINE) self.grid_1 = wx.grid.Grid(self.window_1, -1, size=(1, 1)) self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: MyDialog.__set_properties self.SetTitle("dialog_1") self.grid_1.CreateGrid(10, 3) # end wxGlade def __do_layout(self): # begin wxGlade: MyDialog.__do_layout grid_sizer_1 = wx.FlexGridSizer(1, 2, 3, 3) grid_sizer_1.Add(self.tree_ctrl_1, 1, wx.EXPAND, 0) self.window_1.SplitHorizontally(self.text_ctrl_1, self.grid_1) grid_sizer_1.Add(self.window_1, 1, wx.EXPAND, 0) self.SetSizer(grid_sizer_1) grid_sizer_1.Fit(self) grid_sizer_1.AddGrowableRow(0) grid_sizer_1.AddGrowableCol(0) grid_sizer_1.AddGrowableCol(1) self.Layout() # end wxGlade # end of class MyDialog class MyApp(wx.App): def OnInit(self): wx.InitAllImageHandlers() mainDlg = MyDialog(None, -1, "") self.SetTopWindow(mainDlg) mainDlg.Show() return 1 # end of class MyApp if __name__ == "__main__": app = MyApp(0) app.MainLoop()
This is a very simple layout using wx.aui and three panels. I guess you can easily adapt it to suit your needs.
import wx import wx.aui class MyFrame(wx.Frame): def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) self.mgr = wx.aui.AuiManager(self) leftpanel = wx.Panel(self, -1, size = (200, 150)) rightpanel = wx.Panel(self, -1, size = (200, 150)) bottompanel = wx.Panel(self, -1, size = (200, 150)) self.mgr.AddPane(leftpanel, wx.aui.AuiPaneInfo().Bottom()) self.mgr.AddPane(rightpanel, wx.aui.AuiPaneInfo().Left().Layer(1)) self.mgr.AddPane(bottompanel, wx.aui.AuiPaneInfo().Center().Layer(2)) self.mgr.Update() class MyApp(wx.App): def OnInit(self): frame = MyFrame(None, -1, '07_wxaui.py') frame.Show() self.SetTopWindow(frame) return 1 if __name__ == "__main__": app = MyApp(0) app.MainLoop()
You could consider using the wx.aui advanced user interface module, as it allows you to build UIs like this very easily. Also the user can then minimise, maximise, and drag the panes around as they see fit, or not. It's pretty flexible. I actually find it easier to lay out this sort of UI with the aui toolkit, rather than with grids and splitters. Plus all the fancy buttons make apps look cooler. :)
There is a nice example in the official demos, called AUI_DockingWindowMgr.