I want to apply a QGraphicsDropShadowEffect
and a QGraphicsOpacityEffect
in my PyQt6 application. My goal is to have a widget, that has the QGraphicsDropShadowEffect
and that I can animate the widget’s opacity to fade it in and out depending on the user’s action.
To enable the effects with PyQt6 I use the setGraphicsEffect
method of the widget. Because PyQt6 does not allow to set multiple effects on the same widget, I put parts of the widget in a container. I apply the QGraphicsDropShadowEffect
to a specific widget and the QGraphicsOpacityEffect
to the whole container. Because the opacity is set to 0.7 by default (see this) I want to set it to 1.0 after the effect is created. Here, I get an error.
Here is a minimal example which produces the error:
from PyQt6.QtWidgets import (
QApplication, QWidget, QLabel, QVBoxLayout, QGraphicsDropShadowEffect, QGraphicsOpacityEffect
)
from PyQt6.QtGui import QColor
from PyQt6.QtCore import Qt
import sys
class CircleWidget(QWidget):
def __init__(self):
super().__init__()
# Set up the main layout
layout = QVBoxLayout(self)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
# Create a label to act as the circle with text
self.circle_label = QLabel("Text")
self.circle_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.circle_label.setFixedSize(100, 100) # Set size to create a circle
self.circle_label.setStyleSheet(
"""
QLabel {
background-color: black;
color: white;
border-radius: 50px; /* Half of the width/height to create a circle */
font-size: 20px;
}
"""
)
# Create and set the drop shadow effect
shadow = QGraphicsDropShadowEffect()
shadow.setBlurRadius(15)
shadow.setOffset(5, 5)
shadow.setColor(QColor(0, 0, 0, 160)) # Set shadow color with some transparency
self.circle_label.setGraphicsEffect(shadow)
# Create a container widget to apply opacity effect
container = QWidget()
container_layout = QVBoxLayout(container)
container_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
container_layout.setContentsMargins(0, 0, 0, 0)
container_layout.addWidget(self.circle_label)
# Create and set the opacity effect on the container
opacity_effect = QGraphicsOpacityEffect()
opacity_effect.setOpacity(1.0) # Set the desired opacity level
container.setGraphicsEffect(opacity_effect)
# Add the container with the label to the main layout
layout.addWidget(container)
# Set the layout to the main window
self.setLayout(layout)
self.setWindowTitle("Circle with Effects")
self.setFixedSize(200, 200)
# Initialize the application
app = QApplication(sys.argv)
window = CircleWidget()
window.show()
sys.exit(app.exec())
The error I get:
QPainter::begin: A paint device can only be painted by one painter at a time.
QPainter::translate: Painter not active
QPainter::worldTransform: Painter not active
QWidgetEffectSourcePrivate::pixmap: Painter not active
QPainter::worldTransform: Painter not active
QPainter::setWorldTransform: Painter not active
The strange thing is, that I do not get the error, if I set the opacity to a slightly smaller value, e.g. 0.99.
I am running this app on Ubuntu 24.04.
So I don’t know whether this is a bug or if I am not applying (or stacking) the effects correctly.
2