fuzzboil
fuzzboil

Reputation: 61

Custom widget background color in pyside2

Trying to work out how to set the background color in a QWidget. Here is my code:

class ParentTester(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        left = ColorTester(self)
        right = QFrame(self)
        right.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        layout = QHBoxLayout()
        layout.addWidget(left)
        layout.addWidget(right)
        self.setLayout(layout)


class ColorTester(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(128, 0, 0))
        self.setPalette(palette)

def main():
    import sys
    from PySide2.QtWidgets import QApplication

    app = QApplication([])

    works = True

    if works:
        win = ColorTester()
    else:
        win = ParentTester()
    win.show()
    win.resize(640, 480)

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

This works if I create the class as a topmost window. However if I make it a child of another control, the background color goes back to the default. Some of the other color roles do take effect, but not the background color. Not only that, but the colors get passed through to child controls.

How can I change the background color of a control but not its child controls?

Upvotes: 4

Views: 3510

Answers (2)

fuzzboil
fuzzboil

Reputation: 61

I finally settled on overriding paintEvent for my widget. Setting the color in the palette always seems to pass the color down to child controls, which is not what I wanted. Here is an example of what worked for me. This is a QFrame that takes the default background color and darkens and green-shifts it slightly.

class GreenFrame(QFrame):
    def __init__(self, parent=None):
        super().__init__(parent)
        r, g, b, a = self.palette().color(QPalette.Window).toTuple()
        self._bgcolor = QColor(r * 7 // 8, g, b * 7 // 8)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(event.rect(), self._bgcolor)
        super().paintEvent(event)

Upvotes: 0

eyllanesc
eyllanesc

Reputation: 244361

By default, the child widgets take the color of the window, so you observe that effect, if you want the custom background color to be used then you must enable the autoFillBackground property:

class ColorTester(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(128, 0, 0))
        self.setPalette(palette)
        self.setAutoFillBackground(True)

enter image description here

Upvotes: 4

Related Questions