简体   繁体   中英

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_()

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_())

Children inherit the effect, so all you needed to do is set it on the parent

import sys
from PySide2.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)
        self.shadow.setBlurRadius(16)
        self.shadow.setXOffset(8)
        self.shadow.setYOffset(8)

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

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


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM