views:

1342

answers:

4

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.

+2  A: 

You should use wxSplitter, here's an example. Another one here. And another.

Eli Bendersky
+5  A: 

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()
RSabet
Thanks, that is what I was looking for. Just to be contrary I replicated the layout (somewhat) using XRCed and am using that in my application.
andy47
A: 

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.

Fara
+1  A: 

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()
Orjanp