【问题标题】:PYQT - nesting widgets and layouts in multiple levelsPYQT - 在多个级别中嵌套小部件和布局
【发布时间】:2018-03-03 06:41:06
【问题描述】:

我是 pyqt 的新手,并试图创建一组嵌套容器来保存我的控件。我找不到任何嵌套小部件的示例(并保持它们的布局)。我只能嵌套布局,但这不是我想要实现的。我想这样做的一个原因是控制我的容器的背景颜色。由于布局没有颜色,我想我需要 QWidgets 或 QFrames。这是我走了多远:

class AssetCreationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(AssetCreationWindow, self).__init__()
        self.create_content()
        self.show()

    def create_content(self):

    # creating main container-frame, parent it to QWindow
        self.main_CF = QtWidgets.QFrame(self)
        self.main_CF.setStyleSheet('background-color: rgba(255, 0, 0, 1);')
        self.setCentralWidget(self.main_CF)
    # creating layout and parent it to main container
    # is it correct, that main_CL now manages children of main_CF ?
        self.main_CL = QtWidgets.QVBoxLayout(self.main_CF)

    # creating the first subcontainer + layout, parenting it
        asset_CGF = QtWidgets.QFrame(self.main_CF)
        asset_CGF.setStyleSheet('background-color: rgba(0, 255, 0, 1);')
        asset_CGL = QtWidgets.QHBoxLayout(asset_CGF)

    # creating label and lineEdit, both are supposed to be on top of asset_CGF    
        asset_label = QtWidgets.QLabel("Assetname: ", asset_CGF)
        asset_CGL.addWidget(asset_label)
        asset_name = QtWidgets.QLineEdit("MyNewAsset", asset_CGF)
        asset_CGL.addWidget(asset_name)

    # doing the same with a second container
        department_CGF = QtWidgets.QFrame(self.main_CF)
        department_CGF.setStyleSheet('background-color: rgba(0, 0, 255, 1);')
        department_CGL = QtWidgets.QHBoxLayout(department_CGF)

        department_label = QtWidgets.QLabel("Department: ", department_CGF)
        department_CGL.addWidget(department_label)

        department_names = QtWidgets.QComboBox(department_CGF)
        department_CGL.addWidget(department_names)

不幸的是,这种方法将右上角的所有小部件堆叠在一起。另一种是从除 main_CL 之外的所有布局中删除 ParentWidget 并使用 addLayout()。

def create_content(self):

    self.main_CF = QtWidgets.QFrame(self)
    self.setCentralWidget(self.main_CF)
    self.main_CL = QtWidgets.QVBoxLayout(self.main_CF)

    asset_CGF = QtWidgets.QFrame(self.main_CF)
    asset_CGF.setStyleSheet('background-color: rgba(255, 0, 0, 1);')
    asset_CGL = QtWidgets.QHBoxLayout()
    self.main_CL.addLayout(asset_CGL)

    asset_label = QtWidgets.QLabel("Asset Name: ", asset_CGF)
    asset_CGL.addWidget(asset_label)
    asset_name = QtWidgets.QLineEdit("MyNewAsset", asset_CGF)
    asset_CGL.addWidget(asset_name)

    department_CGF = QtWidgets.QFrame(self.main_CF)
    department_CGF.setStyleSheet('background-color: rgba(0, 255, 0, 1);')
    department_CGL = QtWidgets.QHBoxLayout()
    self.main_CL.addLayout(department_CGL)

    department_label = QtWidgets.QLabel("Department: ", department_CGF)
    department_CGL.addWidget(department_label)
    department_names = QtWidgets.QComboBox(department_CGF)
    department_CGL.addWidget(department_names)

这看起来总体上更好,但子容器布局似乎不知道子容器。即使控制器是子容器的父级,但控制器并不位于子容器之上。子容器再次堆叠在右上角。我无计可施。

【问题讨论】:

  • 你可以展示你想要的图片。

标签: python pyqt pyqt5


【解决方案1】:

您必须将布局设置为小部件。例如

self.main_CL = QtWidgets.QVBoxLayout()
self.main_CF.setLayout(self.main_CL)

然后将子小部件显式添加到布局中。例如

self.main_CL.addWidget(self.asset_CGF)

对子组件遵循相同的模式。

self.asset_CGF.setLayout(self.asset_CGL)
self.asset_CGL.addWidget(...)

实际上,您的第一个示例只缺少两个调用

self.main_CL.addWidget(self.asset_CGF)
self.main_CL.addWidget(department_CGF)

【讨论】:

  • 当你将一个父级传递给布局时:self.main_CL = QtWidgets.QVBoxLayout(self.main_CF),类似于为父级分配一个布局:self.main_CF.setLayout(self.main_CL)
  • 换句话说,只需要这些指令之一。
【解决方案2】:

包括 Aleš Erjavecs 的回答,这是有效的代码示例:

class AssetCreationWindow(QtWidgets.QMainWindow):

def __init__(self, controller):
    super(AssetCreationWindow, self).__init__()
    self.controller = controller
    self.create_content()
    self.show()

def create_content(self):

# creating main container-frame, parent it to QWindow
    self.main_CF = QtWidgets.QFrame(self)
    self.main_CF.setStyleSheet('background-color: rgba(150, 0, 0, 1);')
    self.setCentralWidget(self.main_CF)
# creating layout and parent it to main container
# is it correct, that main_CL now manages children of main_CF ?
    self.main_CL = QtWidgets.QVBoxLayout(self.main_CF)


# creating the first subcontainer + layout, parenting it
    asset_CGF = QtWidgets.QFrame(self.main_CF)
    self.main_CL.addWidget(asset_CGF)
    asset_CGF.setStyleSheet('background-color: rgba(0, 150, 0, 1);')
    asset_CGL = QtWidgets.QHBoxLayout(asset_CGF)

# creating label and lineEdit, both are supposed to be on top of asset_CGF    
    asset_label = QtWidgets.QLabel("Assetname: ", asset_CGF)
    asset_CGL.addWidget(asset_label)
    asset_name = QtWidgets.QLineEdit("MyNewAsset", asset_CGF)
    asset_CGL.addWidget(asset_name)

# doing the same with a second container
    department_CGF = QtWidgets.QFrame(self.main_CF)
    self.main_CL.addWidget(department_CGF)
    department_CGF.setStyleSheet('background-color: rgba(0, 0, 150, 1);')
    department_CGL = QtWidgets.QHBoxLayout(department_CGF)

    department_label = QtWidgets.QLabel("Department: ", department_CGF)
    department_CGL.addWidget(department_label)

    department_names = QtWidgets.QComboBox(department_CGF)
    department_CGL.addWidget(department_names)

结果如下:window with nested QWidgets

【讨论】:

    猜你喜欢
    • 2018-08-14
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2012-09-19
    • 1970-01-01
    • 2011-09-26
    • 2012-07-19
    相关资源
    最近更新 更多