QWidgetのサブクラスの背景色が設定できない


QWidgetのサブクラスの背景色が設定できない

表題通り。解決済み。解決策は記事の下部にある。

QWidgetのサブクラスから作成したWidgetの背景色を設定出来なかった。
だが継承元のQWidget()で同じように試したところ、何故かうまくいった。

なんなのだこれは!

とおもって調べたので一通りまとめておく。

再現コード

# coding: utf-8

from PySide2 import QtWidgets, QtGui, QtCore


class Widget(QtWidgets.QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.setStyleSheet("background-color:red")

        layout = QtWidgets.QVBoxLayout()

        button_widget = QtWidgets.QPushButton()
        button_widget.setText("Inherited widget")

        layout.addWidget(button_widget)

        self.setLayout(layout)


def generate_widget():
    parent_widget = QtWidgets.QWidget()
    parent_widget.setStyleSheet("background-color:red;")

    layout = QtWidgets.QVBoxLayout()

    button_widget = QtWidgets.QPushButton()
    button_widget.setText("QWidget")

    layout.addWidget(button_widget)

    parent_widget.setLayout(layout)

    return parent_widget


class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        hbox = QtWidgets.QHBoxLayout()

        widget = Widget()
        widget2 = generate_widget()

        hbox.addWidget(widget)
        hbox.addWidget(widget2)

        self.setLayout(hbox)


def main():
    app = QtWidgets.QApplication()

    window = Window()
    window.show()

    exit(app.exec_())


if __name__ == "__main__":
    main()

こんな感じでボタンの背景にしか背景色が効いてない。

ナンデ?

Qt Style Sheets Referenceにはこう書いてある。(超意訳)

QWidget

background, background-clip, およびbackground-originのみサポートします。

QWidgetからサブクラス化する場合、以下のようにpaintEventを提供する必要があります。

def paintEvent(self, event):
    opt = QtWidgets.QStyleOption()
    opt.init(self)
    painter = QtGui.QPainter(self)
    style = self.style()
    style.drawPrimitive(QtWidgets.QStyle.PE_Widget, opt, painter, self)

ということで、上記コードをサブクラスに挟めば解消する。
やったね!