如何将 QGraphicsEffect 应用于具有视口的子窗口小部件?

How to apply a QGraphicsEffect to child widgets with a viewport?

我正在尝试将 QGraphicsEffect 应用于给定小部件的所有子小部件,假设是 QDialog。为此,我设置了对话框的图形效果,除了带有视口的子窗口小部件(QScrollAreaQAbstractItemView 等)外,它对所有内容都按预期工作。这些将在调整 window 帧大小时正确渲染(应用效果),但在任何内部更新(重新渲染 QListView 中新选择的项目)时,它会重新渲染而没有效果应用。

我知道您可以将 QGraphicsEffect 分配给 QAbstractScrollArea 的视口,但这对我不起作用,因为我希望能够在所有子控件(效果属性将为 dynamic/animated),并且您不能将相同的效果应用于多个源。

这是一个使用 QListView:

显示奇特渲染的示例
from PySide2 import QtWidgets

d = QtWidgets.QDialog()
d.show()

layout = QtWidgets.QVBoxLayout()
d.setLayout(layout)

lw = QtWidgets.QListWidget()
lw.addItems(["dog", "cat", "fish", "platypus"])
layout.addWidget(lw)

btn = QtWidgets.QPushButton("so fuzzy!")
layout.addWidget(btn)

ge = QtWidgets.QGraphicsBlurEffect()
lw.viewport().setGraphicsEffect(ge)  # assign effect to viewport
d.setGraphicsEffect(ge)  # AND to whole dialog?
ge.setBlurRadius(20)

和截图:

and you can't apply the same [instanced] effect to multiple sources.

在代码的最后几行中,您试图使用相同的实例 class 为两个小部件设置图形效果。唉,你不能!来自 Qt 文档,QGraphicsItem.setGraphicsEffect()

If effect is the installed effect on a different item, will remove the effect from the item and install it on this item.

这里采用的方法是为每个小部件创建一个 QGraphicsEffect 实例。然后,对于 QScrollArea, QAbstractItemView、运行 他们的 find children 方法 (.findChildren(QtWidgets.QWidget) ) 迭代并设置他们的图形效果:

ge = QtWidgets.QGraphicsBlurEffect
d.setGraphicsEffect(ge())

lw.viewport().setGraphicsEffect(ge())

# Find List Widget's child widgets.  Assign their graphics effect.
lw_children = lw.findChildren(QtWidgets.QWidget)
for c in lw_children:
    c.setGraphicsEffect(ge())