使用PySide在QGraphicsScene中选择项目?

时间:2017-10-29 10:20:17

标签: python pyside qgraphicsscene

我需要创建几个可移动的可选图形项。项目保持选中状态,直到选择了其他项目,或者直到用户单击场景的空白部分,取消选择所有项目。所选项目必须与未选择项目看起来不同。主窗口的任何窗口小部件应该能够查询是否选择了图形项目 - 如果是,则选择哪一个。

此代码允许在屏幕上选择和移动项目。移动时项目变为红色:

import sys
from PySide import QtGui, QtCore

class MainWindowUi(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.scene = Scene(0, 0, 300, 300, self)
        self.view = QtGui.QGraphicsView()
        self.setCentralWidget(self.view)
        self.view.setScene(self.scene)
        self.scene.addItem(Line(25,25,25,50))
        self.scene.addItem(Line(30,30,30,70))
        self.scene.addItem(Line(35, 40, 35, 65))

class Scene(QtGui.QGraphicsScene):
    pass

class Line(QtGui.QGraphicsLineItem):
    def __init__(self, *args):
        QtGui.QGraphicsLineItem.__init__(self)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
        self.setPen(QtGui.QPen(QtCore.Qt.black, 3))

    def mousePressEvent(self, e):
        self.setPen(QtGui.QPen(QtCore.Qt.red, 5))
        QtGui.QGraphicsLineItem.mousePressEvent(self, e)

    def mouseReleaseEvent(self, e):
        self.setPen(QtGui.QPen(QtCore.Qt.black, 3))
        QtGui.QGraphicsLineItem.mouseReleaseEvent(self, e)

if __name__ == '__main__':
    a = QtGui.QApplication(sys.argv)
    m = MainWindowUi()
    m.show()
    sys.exit(a.exec_())

以下是我的问题:

  1. 在Qt中,是否在发布时移动和取消选择时选择了图形项目?

  2. 鼠标释放后,图形项目如何保持选中状态?例如,我应该在" Line"中创建一个布尔变量。叫做self.selected?

  3. 应用程序如何查询选择哪个图形项并区分它们?例如,应该是班级中的每个项目" Line"被分配一个唯一的ID或Qt已经这样做了吗?

2 个答案:

答案 0 :(得分:0)

  

在Qt中,是移动和未选中时选择的图形项目   释放?

单击某个项目时会选择一个项目,当您选择其他项目或单击空白区域时会取消选择该项目。

  

鼠标释放后,图形项目如何保持选中状态?对于   例如,我应该在" Line"中创建一个布尔变量。叫   self.selected?

从上一个答案开始,元素仍处于选中状态,此外,已经有函数QGraphicsScene返回True或False以及是否选择了该项。

  

应用程序如何查询选择的图形项目   区分它们?例如,应该是班级中的每个项目   "线"被分配一个唯一的ID或Qt已经这样做了吗?

selectedItems()具有返回所选项目的setData()方法。 Qt没有提供ID或类似的东西,为了执行我们可以使用data()itemChange()方法的任务,第一个通过密钥保存一些信息,另一个使用相同的密钥恢复它。

要检测项目中的更改,您必须覆盖ItemSelectedChange方法,这会为我们提供更改类型和此更改的值。在您的情况下,您应该验证更改必须是def itemChange(self, change, value): if change == QtGui.QGraphicsItem.ItemSelectedChange: if value: self.setPen(QtGui.QPen(QtCore.Qt.red, 3)) else: self.setPen(QtGui.QPen(QtCore.Qt.black, 3)) return QtGui.QGraphicsLineItem.itemChange(self, change, value) 类型,如果选中,则值为True;如果取消选择,则验证为False。

class MainWindowUi(QtGui.QMainWindow):
    def __init__(self, *args, **kwargs):
        QtGui.QMainWindow.__init__(self, *args, **kwargs)
        self.scene = Scene(0, 0, 300, 300, self)
        self.view = QtGui.QGraphicsView(self)
        self.setCentralWidget(self.view)
        self.view.setScene(self.scene)
        self.scene.addItem(Line(25, 25, 25, 50))
        self.scene.addItem(Line(30, 30, 30, 70))
        self.scene.addItem(Line(35, 40, 35, 65))
        self.scene.selectionChanged.connect(self.onSelectionChanged)

    def onSelectionChanged(self):
        message = "Items selecteds: "
        for item in self.scene.selectedItems():
            message += " " + item.data(Scene.NameItem)
        self.statusBar().showMessage(message)


class Scene(QtGui.QGraphicsScene):
    NameItem = 1

    def __init__(self, *args, **kwargs):
        QtGui.QGraphicsScene.__init__(self, *args, **kwargs)
        self.counterItems = 0

    def addItem(self, item):
        item.setData(Scene.NameItem, "item {}".format(self.counterItems))
        self.counterItems += 1
        QtGui.QGraphicsScene.addItem(self, item)


class Line(QtGui.QGraphicsLineItem):
    def __init__(self, *args, **kwargs):
        QtGui.QGraphicsLineItem.__init__(self, *args, **kwargs)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
        self.setPen(QtGui.QPen(QtCore.Qt.black, 3))

    def itemChange(self, change, value):
        if change == QtGui.QGraphicsItem.ItemSelectedChange:
            if value:
                self.setPen(QtGui.QPen(QtCore.Qt.red, 3))
            else:
                self.setPen(QtGui.QPen(QtCore.Qt.black, 3))
        return QtGui.QGraphicsLineItem.itemChange(self, change, value)

示例:

BorderLayout

答案 1 :(得分:0)

  

在Qt中,是移动和未选中时选择的图形项目   释放?

不,默认情况下,鼠标单击时会选中qgraphics项,即使鼠标被释放也会保持选中状态。

  

鼠标释放后,图形项目如何保持选中状态?对于   例如,我应该在“Line”中创建一个布尔变量   self.selected?

qgraphics知道是否已选中,您可以要求它查询其isSelected()方法。

  

应用程序如何查询选择的图形项目   区分它们?例如,应该是班级中的每个项目   “Line”会被分配一个唯一的ID,或者Qt已经这样做了吗?

从应用程序的角度来看,它可以获取调用QGraphicsScene::selectedItems()方法的所有选定项目。

您可能会阅读描述如何使用它的graphics api documentation