简体   繁体   中英

wxpython controls gathered on top left corner

I'm very new to wxpython.

My purpose is to generate a UI that is composed of a two horizontal panels with specific controls. I derived controlPanel from wx.Panel that I want to integrate to the mainFrame. controlPanel is composed of a wx.staticBox and two "sub" wx.StaticBox where some controls are added. Somehow, when the window opens, the controls are displayed on the top-left corners of the staticBox as shown on this image

Can you explain why the controls are not distributed in the staticBoxes from that bunch of code :

import wx
from wx._core import ID_ANY

from collections import namedtuple

class mvtControlPanelUI(wx.Panel):
    m_mainCtrBoxSizer = []
    m_mainCtrStaticBox = []
    m_commonControlsBox = []
    m_customControlsBox = []
    m_inputDataPathStruct = []
    m_outputDataPathStruct = []
    m_commonCtrlSizer = []
    m_inputDataCtrlSizer = []
    m_outputDataCtrlSizer = []

    def __init__(self, parent):
        wx.Panel.__init__(self, parent, name="controlPanel")
        self.SetBackgroundColour('white')
        self.m_mainCtrStaticBox = wx.StaticBox(self, label = "Controls")
        self.m_mainCtrBoxSizer = wx.StaticBoxSizer(self.m_mainCtrStaticBox,
                                  wx.VERTICAL)

        # common controls
        self.initCustomControls()


        self.initCommonControls()
        self.SetSizer(self.m_mainCtrBoxSizer)
        self.Layout()


#     common control initialization
    def initCommonControls(self):

        #input data controls
        self.m_commonControlsBox = wx.StaticBox(self.m_mainCtrStaticBox, -1, "Common controls");
        #common control sizer
        self.m_commonCtrlSizer = wx.StaticBoxSizer(self.m_commonControlsBox, wx.VERTICAL)
        #input data controls sizer
        self.m_inputDataCtrlSizer = wx.BoxSizer(wx.HORIZONTAL)

        # Create the struct
        self.m_inputDataPathStruct = namedtuple("staticText", "editBox", "browseBn")
        # static text
        self.m_inputDataPathStruct.staticText  = wx.StaticText(self.m_commonControlsBox, -1, "Input data path:", style = wx.ALIGN_LEFT)
        self.m_inputDataCtrlSizer.Add(self.m_inputDataPathStruct.staticText, 0, wx.ALL|wx.CENTER, 5)
        # text box 
        self.m_inputDataPathStruct.editBox  = wx.TextCtrl(self.m_commonControlsBox, -1, "/path/to/data/folder", style = wx.ALIGN_LEFT)
        self.m_inputDataCtrlSizer.Add(self.m_inputDataPathStruct.editBox, 0, wx.ALL|wx.CENTER, 5)
        # browse button
        self.m_inputDataPathStruct.browseBn  = wx.Button(self.m_commonControlsBox, -1, "...", style = wx.ALIGN_LEFT)
        self.m_inputDataCtrlSizer.Add(self.m_inputDataPathStruct.browseBn, 0, wx.ALL|wx.CENTER, 5)
        # insert input controls sizer in common control sizer
        self.m_commonCtrlSizer.Add(self.m_inputDataCtrlSizer, 1, wx.ALL|wx.CENTER, 10)
        #add common control box to the mainControl box sizer
        self.m_mainCtrBoxSizer.Add(self.m_commonControlsBox, 1, wx.ALL|wx.EXPAND, 10)


    # 
    def initCustomControls(self):
        self.m_customControlsBox = wx.StaticBox(self.m_mainCtrStaticBox, -1, "custom controls");
        #custom control sizer
        self.m_customCtrlSizer = wx.StaticBoxSizer(self.m_customControlsBox, wx.VERTICAL)

        #static text
        staticText = wx.StaticText(self.m_customControlsBox, -1, "custom Controls go Here", style = wx.ALIGN_LEFT)

        self.m_customCtrlSizer.Add(staticText, 1, wx.ALL|wx.CENTER, 10)
        self.m_mainCtrBoxSizer.Add(self.m_customControlsBox, 4, wx.ALL|wx.EXPAND, 10)

MainFrame :

import wx

import baseUI.mvtControlPanelUI as cPnl
import baseUI.mvtResultsPanelUI as rPnl

TBFLAGS = ( wx.TB_HORIZONTAL
            | wx.NO_BORDER
            | wx.TB_FLAT
            #| wx.TB_TEXT
            #| wx.TB_HORZ_LAYOUT
            )

class mvtMainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, wx.ID_ANY, 'myAwesomeFrame', size=(600, 400))

        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

#       panels
        mainPanel = wx.Panel(self)
        controlPnl =  cPnl.mvtControlPanelUI(mainPanel)
        resultsPnl = rPnl.mvtResultsPanelUI(mainPanel)

#       Main Panel sizer wraps control and results panels
        mainFrameSizer = wx.BoxSizer(wx.VERTICAL)
        mainPnlSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainPnlSizer.Add(controlPnl, proportion = 1, flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP)
        mainPnlSizer.Add(resultsPnl, proportion = 3, flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP)
        mainPanel.SetSizer(mainFrameSizer)

#         mainFrameSizer.Add(self._ribbon, 0, wx.EXPAND)
        mainFrameSizer.Add(mainPnlSizer, 1, wx.EXPAND)

        self.CreateStatusBar()
        self.Layout()

    def OnCloseWindow(self, event):
        self.Destroy()

    def OnFullScreen(self, event):
        self.ShowFullScreen(not self.IsFullScreen(), 0)

The code that follows gives what I think you are looking for (only for one of the panels).
The problem in your code is related with assigning parent and child widgets.
On the other hand, my advise is that you should not complicate your code more than neccesary. Very long names, too verbose names, sometime can hide the code structure.
You can also take advantage of applications like wxglade to build your UIs in a more 'safer' and clean way

import wx

class ControlPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, name="controlPanel")
        self.SetBackgroundColour('white')
        self.mainBox = wx.StaticBox(self, label ="Controls")
        self.mainSizer = wx.StaticBoxSizer(self.mainBox, wx.VERTICAL)

        self.initCustomControls()
        self.initCommonControls()

        self.SetSizer(self.mainSizer)
        self.Layout()

    def initCommonControls(self):
        self.commonBox = wx.StaticBox(self, -1, "Common controls");
        self.commonSizer = wx.StaticBoxSizer(self.commonBox, wx.VERTICAL)

        self.text  = wx.StaticText(self, -1, "Input data path:", style = wx.ALIGN_LEFT)
        self.editBox = wx.TextCtrl(self, -1, "/path/to/data/folder", style=wx.ALIGN_LEFT)
        self.browseBn = wx.Button(self, -1, "...", style=wx.ALIGN_LEFT)

        self.commonSizer.Add(self.text, 0, wx.ALL | wx.CENTER, 5)
        self.commonSizer.Add(self.editBox, 0, wx.ALL | wx.CENTER, 5)
        self.commonSizer.Add(self.browseBn, 0, wx.ALL | wx.CENTER, 5)

        self.mainSizer.Add(self.commonSizer, 1, wx.ALL | wx.EXPAND, 10)

    def initCustomControls(self):
        self.customBox = wx.StaticBox(self, -1, "custom controls");
        self.customSizer = wx.StaticBoxSizer(self.customBox, wx.VERTICAL)

        staticText = wx.StaticText(self, -1, "custom Controls go Here", style = wx.ALIGN_LEFT)

        self.customSizer.Add(staticText, 1, wx.ALL|wx.CENTER, 10)
        self.mainSizer.Add(self.customSizer, 4, wx.ALL | wx.EXPAND, 10)


class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, wx.ID_ANY, 'myAwesomeFrame', size=(400, 400))

        controlPnl = ControlPanel(self)
        mainPnlSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainPnlSizer.Add(controlPnl, proportion = 1, flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP)
        self.SetSizer(mainPnlSizer)
        self.CreateStatusBar()
        self.Layout()


if __name__ == "__main__":
    app = wx.App()
    f = MyFrame(None)
    f.Show(True)
    app.MainLoop()

You get:

在此处输入图片说明

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