You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

QGraphicsView首次拖放后无法触发二次拖放事件问题求助

问题原因及解决方案

我帮你分析了一下,问题出在你每次拖放图片时都会创建新的QGraphicsScene并调用setScene替换旧场景。当视图绑定了场景后,拖放事件会优先被场景处理,而默认情况下QGraphicsSceneacceptDrops属性是False——这就导致第二次拖放时,事件被场景直接忽略,根本传不到你写的dragEnterEvent方法里,自然不会触发啦。

修复方案

核心思路是复用同一个场景,而不是每次拖放都新建场景:

1. 修改DropGraphicsView的初始化方法

在初始化时就创建好场景并绑定到视图,不用每次拖放都重复操作:

def __init__(self, parent):
    super(DropGraphicsView, self).__init__(parent)
    self.setAcceptDrops(True)
    self.image_path = None  # 保存图片路径
    # 初始化一次场景并绑定到视图
    self.scene = QGraphicsScene()
    self.setScene(self.scene)

2. 改写show_image方法

每次显示新图片时,先清空场景里的旧元素,再添加新的图片元素即可,不用重新创建场景:

def show_image(self, image_path):
    # 读取图片
    if isinstance(image_path, str):
        frame = QImage(image_path)
    elif isinstance(image_path, np.ndarray):
        frame = QImage(image_path, image_path.shape[1], image_path.shape[0], QImage.Format_RGB888)
    else:
        warnings.warn("wrong type")
        return
    if frame is not None:
        # 缩放图片适配视图
        size = self.size()
        size.setWidth(size.width() - 2)
        size.setHeight(size.height() - 2)
        frame = frame.scaled(size)
        # 转换为像素图元
        pix = QPixmap.fromImage(frame)
        # 清空场景中的旧元素
        self.scene.clear()
        # 添加新的图片元素
        self.item = QGraphicsPixmapItem(pix)
        self.scene.addItem(self.item)
        # 不需要再调用setScene和show,场景已经绑定且视图已显示

这样修改后,视图始终绑定同一个场景,拖放事件会正常传递到你的dragEnterEvent方法,第二次拖放就能正常触发了,还能避免频繁创建对象的性能损耗哦。

内容的提问来源于stack exchange,提问作者William Chan

火山引擎 最新活动