Select 个项目在 QGraphicsScene 中使用 PySide?
Select items in QGraphicsScene using PySide?
我需要创建几个可移动的、可选择的图形项目。一个项目保持选中状态,直到另一个项目被选中,或者直到用户单击场景的空白部分,取消选择所有项目。选中的项目必须与未选中的项目看起来不同。主要 window 的任何小部件都应该能够查询是否选择了一个图形项目,如果是的话,是哪个。
此代码允许在屏幕上选择和移动项目。移动时项目变红:
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_())
这是我的问题:
在Qt中,图形项是移动时选中,松开时取消选中吗?
鼠标松开后图形项目如何保持选中状态?例如,我是否应该在 "Line" 中创建一个名为 self.selected 的布尔变量?
应用程序如何查询选择了哪个图形项并区分它们?例如,是否应该为 class "Line" 中的每个项目分配一个唯一的 ID,或者 Qt 是否已经这样做了?
Within Qt, is a graphic item selected when moved and unselected when
released?
单击一个项目时选择一个项目,当您选择另一个项目或单击空白区域时取消选择。
How might a graphic item remain selected after mouse release? For
example, should I create a Boolean variable in "Line" called
self.selected?
根据上一个答案,元素保持选中状态,此外已经有函数 selected()
returns True 或 False 以及项目是否被选中。
How can the application query which graphic item is selected and
differentiate between them? For example, should each item in the class
"Line" be assigned a unique ID or does Qt already do that?
QGraphicsScene
有 selectedItems()
方法 returns 选中的项目。 Qt 不提供 ID 或类似的东西,要执行该任务,我们可以使用 setData()
和 data()
方法,第一个通过密钥保存一些信息,另一个使用相同的密钥恢复它。
要检测项目中的更改,您必须重写 itemChange()
方法,这会为我们提供更改类型和此更改的值。在您的情况下,您应该验证更改必须是 ItemSelectedChange
类型,如果选择它则值为 True,如果取消选择则值为 False。
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)
示例:
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)
Within Qt, is a graphic item selected when moved and unselected when
released?
不,默认情况下 qgraphics
项在单击鼠标时会被选中,即使松开鼠标也会保持选中状态。
How might a graphic item remain selected after mouse release? For
example, should I create a Boolean variable in "Line" called
self.selected?
一个qgraphics
项知道它是否被选中,你可以询问它查询它的isSelected()
方法。
How can the application query which graphic item is selected and
differentiate between them? For example, should each item in the class
"Line" be assigned a unique ID or does Qt already do that?
从应用的角度来说,调用QGraphicsScene::selectedItems()
方法可以得到所有选中的item。
您可能会阅读描述如何使用它的 graphics api documentation。
我需要创建几个可移动的、可选择的图形项目。一个项目保持选中状态,直到另一个项目被选中,或者直到用户单击场景的空白部分,取消选择所有项目。选中的项目必须与未选中的项目看起来不同。主要 window 的任何小部件都应该能够查询是否选择了一个图形项目,如果是的话,是哪个。
此代码允许在屏幕上选择和移动项目。移动时项目变红:
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_())
这是我的问题:
在Qt中,图形项是移动时选中,松开时取消选中吗?
鼠标松开后图形项目如何保持选中状态?例如,我是否应该在 "Line" 中创建一个名为 self.selected 的布尔变量?
应用程序如何查询选择了哪个图形项并区分它们?例如,是否应该为 class "Line" 中的每个项目分配一个唯一的 ID,或者 Qt 是否已经这样做了?
Within Qt, is a graphic item selected when moved and unselected when released?
单击一个项目时选择一个项目,当您选择另一个项目或单击空白区域时取消选择。
How might a graphic item remain selected after mouse release? For example, should I create a Boolean variable in "Line" called self.selected?
根据上一个答案,元素保持选中状态,此外已经有函数 selected()
returns True 或 False 以及项目是否被选中。
How can the application query which graphic item is selected and differentiate between them? For example, should each item in the class "Line" be assigned a unique ID or does Qt already do that?
QGraphicsScene
有 selectedItems()
方法 returns 选中的项目。 Qt 不提供 ID 或类似的东西,要执行该任务,我们可以使用 setData()
和 data()
方法,第一个通过密钥保存一些信息,另一个使用相同的密钥恢复它。
要检测项目中的更改,您必须重写 itemChange()
方法,这会为我们提供更改类型和此更改的值。在您的情况下,您应该验证更改必须是 ItemSelectedChange
类型,如果选择它则值为 True,如果取消选择则值为 False。
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)
示例:
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)
Within Qt, is a graphic item selected when moved and unselected when released?
不,默认情况下 qgraphics
项在单击鼠标时会被选中,即使松开鼠标也会保持选中状态。
How might a graphic item remain selected after mouse release? For example, should I create a Boolean variable in "Line" called self.selected?
一个qgraphics
项知道它是否被选中,你可以询问它查询它的isSelected()
方法。
How can the application query which graphic item is selected and differentiate between them? For example, should each item in the class "Line" be assigned a unique ID or does Qt already do that?
从应用的角度来说,调用QGraphicsScene::selectedItems()
方法可以得到所有选中的item。
您可能会阅读描述如何使用它的 graphics api documentation。