如何识别 QGraphicsItem?
How to identify a QGraphicsItem?
我想知道是否有办法获取 QGraphicsItem 的 ID。没什么复杂的。假设我有一个 QGraphicsScene,我在其中创建了许多相同大小和颜色的矩形。即使没有 ID,我如何识别它们?
更新
这是我的一些代码
class Test(QtWidgets.QDialog):
def __init__(self):
super(Test, self).__init__()
loader = QtUiTools.QUiLoader()
self.ui = loader.load(ui_path, self)
self.variables()
self.ui.create_button.clicked.connect(self.creator)
self.scene.focusItemChanged.connect(self.nameDisplay)
def variables(self):
self.scene = QtWidgets.QGraphicsScene()
self.ui.canvas_area.setScene(self.scene)
def creator(self):
rect = self.scene.addRect(-20,-20,40,40, QPen(Qt.red), QBrush(Qt.gray))
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsFocusable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
self.ui.name_line.setText(str(self.scene.focusItem()))
if __name__ == '__main__':
test_window = Test()
test_window.ui.show()
提前致谢!
QGraphicsItem 不是 QObject,因此它不支持 属性 系统,但它对通过 setData()
.
存储属性的支持有限
class Test(QtWidgets.QDialog):
count = 0
# ...
def creator(self):
rect = self.scene.addRect(-20,-20,40,40, QPen(Qt.red), QBrush(Qt.gray))
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsFocusable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setData(0, self.count)
self.count += 1
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
if newFocusItem and newFocusItem.data(0) is not None:
self.ui.name_line.setText('Item {}'.format(newFocusItem.data(0)))
注意:setData()
和 data()
的 key
参数必须是整数,并且无法知道是否设置了(以及设置了哪些)键:您只能检查如果键值不是 None
。如果你需要更复杂的数据映射,你可以使用字典作为值,或者只是子类(见下文)。
重要的是要考虑到,虽然有人可能会尝试为 addRect()
返回的项目设置属性,但这是行不通的:我们应该记住 PyQt 是 Qt 的绑定,所有 python 用于 Qt 对象的对象是 wrappers.
考虑以下因素:
def creator(self):
# ...
rect.id = self.count
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
print(hasattr(newFocusItem, 'id')
这将始终打印 False
,那是因为我们只在 creator
中为包装器引用创建了一个属性,但由于该引用只是本地的并且属性设置在 [=41] =]that reference (not wrapped object), 它将被垃圾收集并且属性将丢失。
一个可能的选择是为每个项目添加一个持久引用:
class Test(QtWidgets.QDialog):
def __init__(self):
# ...
self.items = []
def creator(self):
# ...
rect.id = self.count
self.items.append(rect)
但我建议坚持使用 setData()
选项,因为它更符合 Qt 的工作方式。
或者,我们可以创建一个自定义的 QGraphicsRectItem 子类并使用 self.scene.addItem()
添加它。在这种情况下,python 包装器将持久存在并且属性将被保留:
class MyRect(QtWidgets.QGraphicsRectItem):
def __init__(self, id, x, y, w, h, pen, brush):
super().__init__(x, y, w, h)
self.id = id
self.setPen(pen)
self.setBrush(brush)
class Test(QtWidgets.QDialog):
# ...
def creator(self):
rect = MyRect(self.count, -20, -20, 40, 40, QPen(Qt.red), QBrush(Qt.gray))
self.scene.addItem(rect)
# ...
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
if hasattr(newFocusItem, 'id'):
self.name_line.setText('Item {}'.format(newFocusItem.id))
我想知道是否有办法获取 QGraphicsItem 的 ID。没什么复杂的。假设我有一个 QGraphicsScene,我在其中创建了许多相同大小和颜色的矩形。即使没有 ID,我如何识别它们?
更新 这是我的一些代码
class Test(QtWidgets.QDialog):
def __init__(self):
super(Test, self).__init__()
loader = QtUiTools.QUiLoader()
self.ui = loader.load(ui_path, self)
self.variables()
self.ui.create_button.clicked.connect(self.creator)
self.scene.focusItemChanged.connect(self.nameDisplay)
def variables(self):
self.scene = QtWidgets.QGraphicsScene()
self.ui.canvas_area.setScene(self.scene)
def creator(self):
rect = self.scene.addRect(-20,-20,40,40, QPen(Qt.red), QBrush(Qt.gray))
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsFocusable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
self.ui.name_line.setText(str(self.scene.focusItem()))
if __name__ == '__main__':
test_window = Test()
test_window.ui.show()
提前致谢!
QGraphicsItem 不是 QObject,因此它不支持 属性 系统,但它对通过 setData()
.
class Test(QtWidgets.QDialog):
count = 0
# ...
def creator(self):
rect = self.scene.addRect(-20,-20,40,40, QPen(Qt.red), QBrush(Qt.gray))
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsFocusable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setData(0, self.count)
self.count += 1
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
if newFocusItem and newFocusItem.data(0) is not None:
self.ui.name_line.setText('Item {}'.format(newFocusItem.data(0)))
注意:setData()
和 data()
的 key
参数必须是整数,并且无法知道是否设置了(以及设置了哪些)键:您只能检查如果键值不是 None
。如果你需要更复杂的数据映射,你可以使用字典作为值,或者只是子类(见下文)。
重要的是要考虑到,虽然有人可能会尝试为 addRect()
返回的项目设置属性,但这是行不通的:我们应该记住 PyQt 是 Qt 的绑定,所有 python 用于 Qt 对象的对象是 wrappers.
考虑以下因素:
def creator(self):
# ...
rect.id = self.count
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
print(hasattr(newFocusItem, 'id')
这将始终打印 False
,那是因为我们只在 creator
中为包装器引用创建了一个属性,但由于该引用只是本地的并且属性设置在 [=41] =]that reference (not wrapped object), 它将被垃圾收集并且属性将丢失。
一个可能的选择是为每个项目添加一个持久引用:
class Test(QtWidgets.QDialog):
def __init__(self):
# ...
self.items = []
def creator(self):
# ...
rect.id = self.count
self.items.append(rect)
但我建议坚持使用 setData()
选项,因为它更符合 Qt 的工作方式。
或者,我们可以创建一个自定义的 QGraphicsRectItem 子类并使用 self.scene.addItem()
添加它。在这种情况下,python 包装器将持久存在并且属性将被保留:
class MyRect(QtWidgets.QGraphicsRectItem):
def __init__(self, id, x, y, w, h, pen, brush):
super().__init__(x, y, w, h)
self.id = id
self.setPen(pen)
self.setBrush(brush)
class Test(QtWidgets.QDialog):
# ...
def creator(self):
rect = MyRect(self.count, -20, -20, 40, 40, QPen(Qt.red), QBrush(Qt.gray))
self.scene.addItem(rect)
# ...
def nameDisplay(self, newFocusItem, oldFocusItem, reason):
if hasattr(newFocusItem, 'id'):
self.name_line.setText('Item {}'.format(newFocusItem.id))