如何让继承QGraphicsPathItem的类在拖动时发射信号?(PySide)
解决PySide中QGraphicsPathItem子类拖动时发射信号的问题
针对你遇到的QGraphicsPathItem无法直接发射信号的问题,以下是两种可行方案的具体实现:
方案一:多重继承QGraphicsPathItem与QGraphicsObject
利用多重继承同时获取QGraphicsPathItem的路径属性和QGraphicsObject的信号能力,注意显式初始化两个父类并正确处理事件:
from PySide6.QtWidgets import QGraphicsPathItem, QGraphicsObject from PySide6.QtCore import Signal, QPointF class PathItemWithSignal(QGraphicsPathItem, QGraphicsObject): # 定义拖动信号,参数为当前位置 item_dragged = Signal(QPointF) def __init__(self, parent=None): # 显式调用两个父类的构造函数 QGraphicsPathItem.__init__(self, parent) QGraphicsObject.__init__(self, parent) # 开启可拖动属性 self.setFlag(QGraphicsPathItem.ItemIsMovable) def mouseMoveEvent(self, event): # 先执行父类的事件逻辑,保证正常拖动行为 super().mouseMoveEvent(event) # 发射拖动后的位置信号 self.item_dragged.emit(self.pos())
方案二:内嵌QObject子类作为信号载体
如果担心多重继承的潜在冲突,可以通过组合方式,在QGraphicsPathItem子类中内嵌一个QObject实例来处理信号:
from PySide6.QtWidgets import QGraphicsPathItem from PySide6.QtCore import Signal, QObject, QPointF # 单独定义信号发射类 class SignalEmitter(QObject): item_dragged = Signal(QPointF) class PathItemWithSignal(QGraphicsPathItem): def __init__(self, parent=None): super().__init__(parent) self.setFlag(QGraphicsPathItem.ItemIsMovable) # 初始化信号发射子对象 self._emitter = SignalEmitter() # 将子对象的信号暴露给外部,方便直接连接 self.item_dragged = self._emitter.item_dragged def mouseMoveEvent(self, event): super().mouseMoveEvent(event) # 通过子对象发射信号 self._emitter.item_dragged.emit(self.pos())
使用示例
无论采用哪种方案,外部连接信号的方式一致:
if __name__ == "__main__": import sys from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QGraphicsView, QGraphicsScene from PySide6.QtGui import QPainterPath app = QApplication(sys.argv) window = QWidget() layout = QVBoxLayout(window) view = QGraphicsView() scene = QGraphicsScene() view.setScene(scene) layout.addWidget(view) # 创建自定义路径项 item = PathItemWithSignal() # 设置示例路径(矩形) path = QPainterPath() path.addRect(0, 0, 100, 100) item.setPath(path) scene.addItem(item) # 连接拖动信号 def handle_drag(pos): print(f"Item moved to: ({pos.x():.2f}, {pos.y():.2f})") item.item_dragged.connect(handle_drag) window.show() sys.exit(app.exec())
内容的提问来源于stack exchange,提问作者Moon_Raven
相关产品推荐
相关产品推荐

