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.

Answers


First of all download wxGlade a gui builder for wxPython (alternative XRCed, i prefere wxGlade).

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).

Regards.

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.

Orjanp...

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 should use wxSplitter, here's an example. Another one here. And another.


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.


Need Your Help

Mercurial + TeamCity - Recommended setup

mercurial teamcity

Does anyone have any recommended best practice for setting up TeamCity with Mercurial? We'd previously been using SVN as our source control provider which worked beautifully, but I'm struggling to ...

Multi Device Hybrid App - Ripple using old Cordova version

cordova visual-studio-2013 ripple multi-device-hybrid-apps

We are in the process of switching our development from Redgates VSNomad to Microsoft Multi Device Hybrid App and I've run into a problem using he Ripple emulator.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.