質問

Consider the following example code:

from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QLabel, QWidget,
                             QMainWindow, QVBoxLayout, QTextEdit)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        cwidget = QWidget(self)
        cwidget.setStyleSheet("QWidget { background-color: red; }")
        self.setCentralWidget(cwidget)
        self.resize(100, 100)

        vbox = QVBoxLayout(cwidget)
        vbox.addWidget(QTextEdit(self))
        vbox.addWidget(BlackBar(self))

class BlackBar(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setStyleSheet("* { background-color: black; color: white; }")
        hbox = QHBoxLayout(self)
        hbox.setSpacing(5)
        hbox.addWidget(QLabel(text="eggs"))
        hbox.addWidget(QLabel(text="bacon"))

if __name__ == '__main__':
    app = QApplication([])
    main = MainWindow()
    main.show()
    app.exec_()

It has:

  • A QMainWindow, QWidget as central widget (red), QVBoxLayout as a child of the cental widget. Inside there:
    • A QTextEdit (just as a filler)
    • A QWidget (black), which contains a QHBoxLayout. Inside that:
      • Two QLabels

This looks like this:

Qt HBoxLayout

I'd expect the spaces between the labels to be black, because the QHBoxLayout is a child of BlackBar, but it seems BlackBar is just "invisible" in between and the central widget "shines through". Why is this?

役に立ちましたか?

解決

The bugreport has now been answered with a solution that's easier than @ekhumoro's answer and works:

I don't think this is valid. The paint code your are looking for is not drawn in the paintEvent. Look for QWidgetPrivate::paintBackground instead. For performance reasons widgets will ignore style sheets by default, but you can set the WA_StyledBackground attribute on the widget and it should respect style sheet backgrounds.

And indeed, doing this before setting the stylesheet does the trick:

self.setAttribute(Qt.WA_StyledBackground)

他のヒント

Although the Style Sheet Syntax does not mention it, it seems that the QWidget class is treated differently when it comes to stylesheets.

Other widgets will work fine with your example code. For example, if QWidget is replaced everywhere with QFrame, then everything works as expected.

To get stylesheet support for QWidget subclasses, you need to reimplement the paintEvent and enable it explicitly:

class BlackBar(QWidget):
...
    def paintEvent(self, event):
        option = QStyleOption()
        option.initFrom(self)
        painter = QPainter(self)
        self.style().drawPrimitive(
            QStyle.PE_Widget, option, painter, self)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top