【问题标题】:add background color to a layout which is a sublayout (inside another layout)将背景颜色添加到作为子布局的布局(在另一个布局内)
【发布时间】:2019-12-01 12:38:00
【问题描述】:

布局结构:

self.mainLayout = QGridLayout()
self.subLayout1 = QGridLayout()
self.subLayout2 = QVBoxLayout()
...
...
... 
self.mainLayout.addLayout(subLayout1,0,0)

我试过了:

self.mainLayout = QGridLayout()
self.panel = QWidget()
self.subLayout1 = QGridLayout(self.panel) 
self.mainLayout.addLayout(subLayout1,0,0)
self.panel.setStylesheet("background-color: red;")
Error: QLayout::addChildLayout: layout "" already has a parent

这就是我设置 mainLayout 颜色的方式

self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.black)
        self.setPalette(p)

显示subLayout1、subLayout2等时需要在背面

我该怎么做?

编辑:添加了 MCVE(一个最小的、完整的、可验证的示例)

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QGridLayout
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
from PyQt5.QtCore import Qt


class Window(QMainWindow):

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.setWindowTitle('MCVE')

        '''Window Background'''
        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.darkYellow)
        self.setPalette(p)

        '''Core Layouts'''
        self.mainLayout = QGridLayout()
        self.picLayout = QHBoxLayout()
        self.redditSubs = QVBoxLayout()
        self.downloadBar = QHBoxLayout()
        self.panel = QWidget()
        self.profileInfo = QGridLayout(self.panel)

        '''Nested Layout'''
        self.mainLayout.addLayout(self.profileInfo, 0, 0)
        self.mainLayout.addLayout(self.picLayout, 0, 1)
        self.mainLayout.addLayout(self.redditSubs, 1, 0)
        self.mainLayout.addLayout(self.downloadBar, 1, 1)

        '''Widgets'''
        self.display = QLabel('QHBoxLayout()')
        self.download = QLabel('QHBoxLayout()')
        self.subs = QLabel('QVBoxLayout()')
        self.fileInfo = QLabel('QGridLayout()')

        '''AddWidgets'''
        self.picLayout.addWidget(self.display)
        self.downloadBar.addWidget(self.download)
        self.redditSubs.addWidget(self.subs)
        self.profileInfo.addWidget(self.fileInfo, 0, 0)

        '''Stylesheet'''
        self.panel.setStyleSheet("background-color: red;")

        '''Initiating  mainLayout '''
        self.window = QWidget()
        self.window.setLayout(self.mainLayout)
        self.setCentralWidget(self.window)


if __name__ == '__main__':
    app = QApplication([])
    w = Window()
    w.showNormal()
    app.exec_()

如上所述,代码错误 QLayout::addChildLayout: layout "" 已经有一个父级,如果样式表部分被注释掉,QGridLayout() 标签会显示在该深黄色背景之上,我希望该背景部分是红色。

【问题讨论】:

  • 添加小部件,而不是子布局:self.mainLayout.addWidget(self.panel, row, column)
  • @ekhumoro 所以问题是,我将在 GridLayout 中添加按钮、标签或其他内容。它不仅仅是关于 0,0 mainLayout 单元格的颜色。

标签: python pyqt pyqt5 qlayout


【解决方案1】:

QXLayout 不是一个视觉元素,而是一个类,它控制位置,尤其是分配的小部件的大小。因此,想要为该类设置不是视觉元素的颜色是没有意义的。

另一方面,错误是因为以下两个代码是等效的:

x = QXLayout(w)
x = QXLayout()
w.setLayout(x)

在您的情况下,您已使用以下代码表明布局“profileInfo”属于“面板”:self.profileInfo = QGridLayout(self.panel),但随后您通过以下代码表明相同的布局属于“mainLayout”:self.mainLayout.addLayout(self.profileInfo, 0, 0) .因此,为避免出现警告,您必须通过将最后一个代码替换为 self.mainLayout.addWidget(self.panel, 0, 0)

更新:

如果您希望一个小部件位于另一个小部件内,那么它必须是第二个小部件的子级,因此“fileInfo”必须是“面板”的子级,但由于您希望它占据整个大小那么你必须使用一个布局。

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QGridLayout
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
from PyQt5.QtCore import Qt


class Window(QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.setWindowTitle("MCVE")

        """Window Background"""
        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.darkYellow)
        self.setPalette(p)

        """Core Layouts"""
        self.mainLayout = QGridLayout()
        self.picLayout = QHBoxLayout()
        self.redditSubs = QVBoxLayout()
        self.downloadBar = QHBoxLayout()
        self.profileInfo = QGridLayout()

        """Nested Layout"""
        self.mainLayout.addLayout(self.profileInfo, 0, 0)
        self.mainLayout.addLayout(self.picLayout, 0, 1)
        self.mainLayout.addLayout(self.redditSubs, 1, 0)
        self.mainLayout.addLayout(self.downloadBar, 1, 1)

        """Widgets"""
        self.display = QLabel("QHBoxLayout()")
        self.download = QLabel("QHBoxLayout()")
        self.subs = QLabel("QVBoxLayout()")

        self.fileInfo = QLabel("QGridLayout()")

        self.panel = QWidget()

        """AddWidgets"""
        self.picLayout.addWidget(self.display)
        self.downloadBar.addWidget(self.download)
        self.redditSubs.addWidget(self.subs)
        self.profileInfo.addWidget(self.panel, 0, 0)

        lay = QVBoxLayout(self.panel)
        lay.addWidget(self.fileInfo)

        """Stylesheet"""
        self.panel.setStyleSheet("background-color: red;")

        """Initiating  mainLayout """
        self.window = QWidget()
        self.window.setLayout(self.mainLayout)
        self.setCentralWidget(self.window)


if __name__ == "__main__":
    app = QApplication([])
    w = Window()
    w.showNormal()
    app.exec_()

【讨论】:

  • 好的,但是如何将self.profileInfo.addWidget(self.fileInfo, 0, 0) 放在self.mainLayout.addWidget(self.panel, 0, 0) 前面?
  • @CURVX 我认为您混淆了概念,如果您想要一种视觉行为,最好放置一张您现在拥有的和想要获得的图像,以便轻松理解自己。
  • 所以替换后,我得到了类似link 的东西,我所追求的是 AFTER。稍微挖掘了一下,遇到了stackUnder(),不知道是什么。在self.panel 的样式表中尝试过z-index: -1;。感谢您的耐心等待
  • 工作!我仍然无法绕开我的头,如何? ?……还有很长的路要走。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 2013-01-24
  • 2015-03-16
  • 2011-06-15
相关资源
最近更新 更多