简体   繁体   中英

How to make nested Panel and Sizer work in wxpython

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?

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

The basic form of my applications goes something like this (parent --> child):

frame --> panel --> sizer --> widgets/sizers

For certain things, I do this:

frame --> sizer --> panel --> sizer --> widgets/sizers

I nest sizers are the time. You usually want to sketch out your GUI on paper when you're a new programmer and then draw boxes around them to try to figure out which sizers work, where you'll want to nest them, etc.

You could fix this problem just by changing self.SetSizerAndFit(mainSzr) to posPnl.SetSizerAndFit(mainSzr)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM