首页 > 解决方案 > wxpython 控件聚集在左上角

问题描述

我对 wxpython 很陌生。

我的目的是生成一个由两个带有特定控件的水平面板组成的 UI。我从 wx.Panel 派生了我想要集成到 mainFrame 的 controlPanel。controlPanel 由一个 wx.staticBox 和两个“子” wx.StaticBox 组成,其中添加了一些控件。不知何故,当窗口打开时,控件显示在 staticBox 的左上角,如图 所示

你能解释一下为什么控件没有从那一堆代码中分布在 staticBoxes 中:

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)

主机:

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)

标签: pythonuser-interfacewxpython

解决方案


下面的代码给出了我认为您正在寻找的内容(仅适用于其中一个面板)。
您的代码中的问题与分配父小部件和子小部件有关。
另一方面,我的建议是你不应该让你的代码过于复杂。很长的名字,过于冗长的名字,有时会隐藏代码结构。
您还可以利用 wxglade 等应用程序以更“安全”和更简洁的方式构建您的 UI

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

你得到:

在此处输入图像描述


推荐阅读