How to make nested Panel and Sizer work in wxpython

python, wxpython

Solution

The logic here is to create a `Panel` to add controls inside, then a `BoxSizer` where you declare how each control you add in the `Panel` behaves with resizing, and eventually to set on the `Panel` what is the `BoxSizer` applied on it.

You have 2 issues.

First you are missing the last part of the above statement for the `posPnl`object. Add this:

posPnl.SetSizer(posPnlSzr)

once you have added the controls to `posPnlSzr`

The second issue is that you are adding `posSnlSzr` in your `mainSzr`. It is wrong to do so. Again the logic is to add controls to a sizer, and you can view a `Panel` as a compounded control. Thus the correct code is to add `posPnl` into the `mainSzr`:

mainSzr.Add(posPnl)

As far I as read, you are trying to get `posPnl` automatically resized with the main window. If to add the panel so that `mainSzr` will actually resize it:

mainSzr.Add(posPnl, 1, wx.GROW)

This gives the final source code:

#!/usr/bin/env python

import wx
class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent)

        #add position panel
        posPnl = wx.Panel(self)
        lbl1 = wx.StaticText(posPnl, label="Position")
        lbl2 = wx.StaticText(posPnl, label="Size")
        sizeCtrl = wx.TextCtrl(posPnl)

        posPnlSzr = wx.BoxSizer(wx.HORIZONTAL)
        posPnlSzr.Add(lbl1, 1, wx.GROW)
        posPnlSzr.Add(sizeCtrl, 1, wx.GROW)
        posPnlSzr.Add(lbl2, 1, wx.GROW)

        posPnl.SetSizer(posPnlSzr)

        #create a top leverl sizer to add to the frame itself
        mainSzr = wx.BoxSizer(wx.VERTICAL)
        mainSzr.Add(posPnl, 1, wx.GROW)

        self.SetSizerAndFit(mainSzr)
        self.Show()


app = wx.App(False)
frame = MainWindow(None, "Trading Client")
app.MainLoop()

Problem

I am learning wxpython and trying to get a nested panel to work. This is an exercise to prepare for a more complex screen, hence it may look a bit complicated, but that is with a purpose ;). What I want to do is the following: Create a top frame Add a panel to it add some text and an input field to it Use a vertical boxsizer to do the panel lay out Here is how I implemented it: ``` import wx class MainWindow(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent) #add position panel posPnl = wx.Panel(self) lbl1 = wx.StaticText(posPnl, label="Position") lbl2 = wx.StaticText(posPnl, label="Size") sizeCtrl = wx.TextCtrl(posPnl) posPnlSzr = wx.BoxSizer(wx.HORIZONTAL) posPnlSzr.Add(lbl1, 1, wx.GROW) posPnlSzr.Add(sizeCtrl, 1, wx.GROW) posPnlSzr.Add(lbl2, 1, wx.GROW) #create a top leverl sizer to add to the frame itself mainSzr = wx.BoxSizer(wx.VERTICAL) mainSzr.Add(posPnlSzr) self.SetSizerAndFit(mainSzr) self.Show() app = wx.App(False) frame = MainWindow(None, "Trading Client") app.MainLoop() ``` All i get is a small blank screen with the word 'Pos' on it. What am I doing wrong here?

Original source