Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using QGraphicsDropShadowEffect with multiple widgets

I want to set a shadow on several widgets using QGraphicsDropShadowEffect and I am wondering if there is a better way to do so without having to write the same code over and over again for every instance where I want to use it like in my example below. Is it possible to create a class or something to call so that I just have to set setGraphicsEffect() on the widgets? I have tried to create a few classes for it but I was still only able to get them to create one shadow.

import sys
from PyQt5.QtWidgets import QWidget, QHBoxLayout, \
    QGraphicsDropShadowEffect, QPushButton, QApplication, QComboBox


class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        layout = QHBoxLayout()

        self.shadow = QGraphicsDropShadowEffect()
        self.shadow.setBlurRadius(5)
        self.shadow.setXOffset(3)
        self.shadow.setYOffset(3)

        self.shadow2 = QGraphicsDropShadowEffect()
        self.shadow2.setBlurRadius(5)
        self.shadow2.setXOffset(3)
        self.shadow2.setYOffset(3)

        self.btn = QPushButton("Button")
        self.btn.setGraphicsEffect(self.shadow)
        self.combo = QComboBox()
        self.combo.setGraphicsEffect(self.shadow2)

        layout.addWidget(self.btn)
        layout.addWidget(self.combo)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()
like image 314
Richard Avatar asked Dec 23 '22 04:12

Richard


1 Answers

The docs states that the same QGraphicsEffect can not be shared by other widgets:

If effect is the installed effect on a different widget, setGraphicsEffect() will remove the effect from the widget and install it on this widget.

So you will have to create a QGraphicsEffect for each widget, but if you do not want to write a lot of code and want to apply effects with similar characteristics you could iterate through the widgets and for that you can use findChildren(...).

import sys
from PyQt5.QtWidgets import QWidget, QHBoxLayout, \
    QGraphicsDropShadowEffect, QPushButton, QApplication, QComboBox


class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        layout = QHBoxLayout(self)

        self.btn = QPushButton("Button")
        self.combo = QComboBox()

        layout.addWidget(self.btn)
        layout.addWidget(self.combo)

        for child in self.findChildren(QWidget):
            shadow = QGraphicsDropShadowEffect(blurRadius=5, xOffset=3, yOffset=3)
            child.setGraphicsEffect(shadow)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
like image 113
eyllanesc Avatar answered Jan 05 '23 12:01

eyllanesc