使用来自 QGraphicsScene 的 selectionChanged 信号在所选项目周围添加矩形

Using selectionChanged signal from QGraphicsScene to addRect around selected items

我正在尝试围绕场景中选定的项目绘制一个矩形(通过 RubberBandDrag 或 ctrl+click 为每个项目)。

为了做到这一点,我将 QGraphicsScene 子类化并重新实现了 selectionChanged 方法以在所选区域周围添加 QGraphicsRectItem,但由于某种原因,当项目被选中或未被选中时不会调用此方法在现场。我已确保这些项目实际上是可选择的。

这是我正在尝试做的一个最小示例:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys  

class DiagramScene(QGraphicsScene):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.selRect = None

    def selectionChanged(self):
        area = self.selectionArea().boundingRect()
        pen = QPen()
        pen.setColor(Qt.black)
        pen.setStyle(Qt.DashLine)

        self.selRect = self.addRect(area, pen)


if __name__ == "__main__":

    app = QApplication(sys.argv)

    view = QGraphicsView()
    view.setDragMode(QGraphicsView.RubberBandDrag)

    scene = DiagramScene()

    scene.setSceneRect(0, 0, 500, 500)

    rect1 = scene.addRect(20, 20, 100, 50)
    rect2 = scene.addRect(80, 80, 100, 50)
    rect3 = scene.addRect(140, 140, 100, 50)

    rect1.setFlag(QGraphicsItem.ItemIsSelectable, True)
    rect2.setFlag(QGraphicsItem.ItemIsSelectable, True)
    rect3.setFlag(QGraphicsItem.ItemIsSelectable, True)

    view.setScene(scene)
    view.show()

    sys.exit(app.exec_())

selectionChanged 是一个信号,而不是你必须实现的方法。您需要做的是将此信号连接到槽和槽中的实现,因此无论何时发出信号,您的代码都会执行:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys  

class DiagramScene(QGraphicsScene):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.selRect = None
        self.selectionChanged.connect(self.onSelectionChanged)

    @pyqtSlot()
    def onSelectionChanged(self):
        area = self.selectionArea().boundingRect()
        pen = QPen()
        pen.setColor(Qt.black)
        pen.setStyle(Qt.DashLine)
        self.selRect = self.addRect(area, pen)


if __name__ == "__main__":

    app = QApplication(sys.argv)

    view = QGraphicsView()
    view.setDragMode(QGraphicsView.RubberBandDrag)

    scene = DiagramScene()

    scene.setSceneRect(0, 0, 500, 500)

    rect1 = scene.addRect(20, 20, 100, 50)
    rect2 = scene.addRect(80, 80, 100, 50)
    rect3 = scene.addRect(140, 140, 100, 50)

    rect1.setFlag(QGraphicsItem.ItemIsSelectable, True)
    rect2.setFlag(QGraphicsItem.ItemIsSelectable, True)
    rect3.setFlag(QGraphicsItem.ItemIsSelectable, True)

    view.setScene(scene)
    view.show()

    sys.exit(app.exec_())