You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加QGraphicsBlurEffect后QGraphicsView失效,该如何解决?

PyQt5中QGraphicsItem添加模糊效果后交互失效、显示异常问题

在PyQt5中使用QGraphicsView组件并创建自定义QGraphicsItem时,未添加效果前元素显示正常。但在自定义元素的祖父类GameDisplayedElement中添加以下模糊效果代码后:

blur = _QtWidgets.QGraphicsBlurEffect()
blur.setBlurRadius(1.1)
self.setGraphicsEffect(blur)

出现两个核心问题:

  • 元素显示异常
  • 所有元素无法移动、鼠标交互完全失效

尝试过调整模糊参数,问题依旧;直接给QGraphicsView添加模糊效果,仅在视图resize时生效,元素更新时无效果。

【编辑】修正所有元素的bounding rect后,显示问题有所改善,但动画、鼠标交互等问题仍未解决。

复现代码

替换代码中两个元素paint方法里的图片路径即可测试,添加模糊代码后鼠标无法移动、背景无法自适应窗口大小,移除则恢复正常:

from PyQt5 import QtWidgets as _QtWidgets, uic as _uic
from PyQt5 import QtCore as _QtCore
from PyQt5 import QtGui as _QtGui

class GameWidget(_QtWidgets.QGraphicsView):
    def __init__(self):
        super().__init__()
        
        self._scene: _QtWidgets.QGraphicsScene = _QtWidgets.QGraphicsScene()
        
        self.setScene(self._scene)
        
        self._main_graphic = MainDisplayedElement()
        self._main_graphic.setZValue(-10)
        self._scene.addItem(self._main_graphic)
        
        self._mouse = MouseDisplayedElement()
        self._mouse.set_size(40)
        
        self._mouse.setZValue(1000)
        
        self._scene.addItem(self._mouse)
        
        self.setMouseTracking(True)
        self.setInteractive(True)
        
        self.setVerticalScrollBarPolicy(_QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(_QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        
    def onShow(self):
        self.resizeEvent()
    
    def resizeEvent(self, event = None) -> None:
        w, h = self.width() - 2, self.height() - 2
        
        self.setSceneRect(-w / 2, -h / 2, w, h)
        self._main_graphic.set_rect(-w / 2, -h / 2, w, h)
    
    def mouseMoveEvent(self, event: _QtGui.QMouseEvent) -> None:
        super().mouseMoveEvent(event)
        
        position: _QtCore.QPointF = event.pos()
        
        position.setX(int(position.x() - self.width() / 2))
        position.setY(int(position.y() - self.height() / 2))
        
        event.ignore()
        
        x, y = position.x(), position.y()
        self._mouse.set_position(x, y)
        
        self._scene.update()

class GameDisplayedElement(_QtWidgets.QGraphicsObject):
    def __init__(self, x: int, y: int, width: int, height: int, parent = None):
        super().__init__(parent)
        
        self._width: int = width
        self._height: int = height
        self._x: int = x
        self._y: int = y
        
        self.setAcceptHoverEvents(True)
        self.setAcceptedMouseButtons(_QtCore.Qt.MouseButton.AllButtons)
        
        # 模糊效果代码
        blur = _QtWidgets.QGraphicsBlurEffect()
        blur.setBlurRadius(1.1)
        blur.setBlurHints(_QtWidgets.QGraphicsBlurEffect.BlurHint.QualityHint)
        self.setGraphicsEffect(blur)
        
    def paint(self, painter: _QtGui.QPainter, options: _QtWidgets.QStyleOptionGraphicsItem, widget: _QtWidgets.QWidget) -> None:
        pass
    
    def boundingRect(self) -> _QtCore.QRectF:
        x = self._x - self._width / 2
        y = self._y - self._height / 2
        
        return _QtCore.QRectF(int(x), int(y), int(self._width), int(self._height))

class MainDisplayedElement(GameDisplayedElement):
    def __init__(self, parent=None):
        super().__init__(0, 0, 0, 0)
        
        self._size = 150
        
        self.setAcceptHoverEvents(False)
        self.setAcceptedMouseButtons(_QtCore.Qt.MouseButton.NoButton)
    
    def paint(self, painter: _QtGui.QPainter, options: _QtWidgets.QStyleOptionGraphicsItem, widget: _QtWidgets.QWidget) -> None:
        a = open("./any_image.png", "rb")
        data = a.read()
        a.close()
        
        image = _QtGui.QImage.fromData(data) # 替换为任意QImage
    
        x = 0
        while x - self._size <= self._width / 2:
            y = 0
            while y - self._size <= self._height / 2:
                painter.drawImage(_QtCore.QRectF(x, y, self._size, self._size), image)
                painter.drawImage(_QtCore.QRectF(-x-self._size, y, self._size, self._size), image)
                painter.drawImage(_QtCore.QRectF(x, -y-self._size, self._size, self._size), image)
                painter.drawImage(_QtCore.QRectF(-x-self._size, -y-self._size, self._size, self._size), image)
                y += self._size
            x += self._size
    
    def set_rect(self, x: float, y: float, w: float, h: float) -> None:
        self._x = 0
        self._y = 0
        self._width = w
        self._height = h
    
class MouseDisplayedElement(GameDisplayedElement):
    def __init__(self, parent = None):
        super().__init__(0, 0, 50, 50, parent)
        
        self.setAcceptHoverEvents(False)
        self.setAcceptedMouseButtons(_QtCore.Qt.MouseButton.NoButton)
    
    def paint(self, painter: _QtGui.QPainter, options: _QtWidgets.QStyleOptionGraphicsItem, widget: _QtWidgets.QWidget) -> None:
        a = open("./any_image.png", "rb")
        data = a.read()
        a.close()
        
        image = _QtGui.QImage.fromData(data) # 替换为任意QImage
    
        painter.drawImage(_QtCore.QRectF(self._x, self._y, self._width, self._height), image)
    
    def set_size(self, size: int) -> None:
        self._width, self._height = size, size
    
    def hoverMoveEvent(self, event: _QtGui.QHoverEvent) -> None:
        event.ignore()
    
    def mousePressEvent(self, event):
        event.ignore()
        
    def set_position(self, x: int, y: int) -> None:
        self._x = x
        self._y = y
    
app = _QtWidgets.QApplication([''])

widg = GameWidget()
widg.show()

app.exec()

环境信息

  • Python 3.10.12
  • PyQt5 及 Qt 5.15.3
  • 运行环境:x86-64 架构的 Ubuntu 22.04 LTS

内容的提问来源于stack exchange,提问作者Kaki In

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:15:14