在鼠标双击位置创建一个QGraphicsItem
Create a QGraphicsItem at the mouse double-click position
我正在编写一个程序,当双击发生时(在场景区域内)应该创建一个 QGraphicsItem,并且该项目必须在双击位置创建。我已经写了一些代码,但它不能正常工作。当我双击场景时,一个项目被创建,但在一个完全不同的地方。所以现在这就是问题所在。我需要在鼠标位置创建它。
这是我的代码:
ui_path = "C:/Users/User/Desktop/programming/Creator/Creator.ui"
class Creator(QtWidgets.QWidget):
count = 0
def __init__(self):
super(Creator, self).__init__()
loader = QtUiTools.QUiLoader()
self.ui = loader.load(ui_path, self)
self.variables()
self.ui.canvas_area.viewport().installEventFilter(self) #canvas_area is the QGraphicsView
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint)
def variables(self):
self.scene = QtWidgets.QGraphicsScene()
self.ui.canvas_area.setScene(self.scene)
def eventFilter(self, obj, event):
if obj is self.ui.canvas_area.viewport():
if event.type() == QtCore.QEvent.MouseButtonDblClick:
self.createItems(event)
return super(Creator, self).eventFilter(obj, event)
def createItems(self, event):
pos = event.pos()
self._x = pos.x()
self._y = pos.y()
rect = self.scene.addRect(self._x, self._y, 40, 40, QPen(Qt.red), QBrush(Qt.gray))
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsFocusable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
if __name__ == '__main__':
creator_window = Creator()
creator_window.ui.show()
我已经阅读了一些有关 mapFromScene 和 mapToScene 的内容,它们可以解决问题 - 但我不太了解如何使用它们。也有一些这样的例子,但我发现的都是用 C++ 编写的,我对此一无所知。因此,如果有人可以帮助我弄清楚如何解决这个问题,我将不胜感激。
您首先必须为场景设置场景矩形:
self.scene.setSceneRect(0, 0, 1000, 1000)
然后你必须将事件位置转换为场景坐标,像这样:
pos = self.canvas_area.mapToScene(event.pos())
这应该是修复您的示例所需的全部内容。
另一种可能值得考虑的方法是在场景中安装事件过滤器:
self.scene.installEventFilter(self)
然后过滤更专业的 graphics events:
def eventFilter(self, obj, event):
if obj is self.scene:
if event.type() == QtCore.QEvent.GraphicsSceneMouseDoubleClick:
self.createItems(event)
return super(Creator, self).eventFilter(obj, event)
这会创建一个 QGraphicsSceneMouseEvent, which has several useful features that a standard QMouseEvent doesn't have. This includes scenePos(),这样就不必一直映射到场景坐标,这样您就可以简单地执行以下操作:
pos = event.scenePos()
我正在编写一个程序,当双击发生时(在场景区域内)应该创建一个 QGraphicsItem,并且该项目必须在双击位置创建。我已经写了一些代码,但它不能正常工作。当我双击场景时,一个项目被创建,但在一个完全不同的地方。所以现在这就是问题所在。我需要在鼠标位置创建它。
这是我的代码:
ui_path = "C:/Users/User/Desktop/programming/Creator/Creator.ui"
class Creator(QtWidgets.QWidget):
count = 0
def __init__(self):
super(Creator, self).__init__()
loader = QtUiTools.QUiLoader()
self.ui = loader.load(ui_path, self)
self.variables()
self.ui.canvas_area.viewport().installEventFilter(self) #canvas_area is the QGraphicsView
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint)
def variables(self):
self.scene = QtWidgets.QGraphicsScene()
self.ui.canvas_area.setScene(self.scene)
def eventFilter(self, obj, event):
if obj is self.ui.canvas_area.viewport():
if event.type() == QtCore.QEvent.MouseButtonDblClick:
self.createItems(event)
return super(Creator, self).eventFilter(obj, event)
def createItems(self, event):
pos = event.pos()
self._x = pos.x()
self._y = pos.y()
rect = self.scene.addRect(self._x, self._y, 40, 40, QPen(Qt.red), QBrush(Qt.gray))
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect.setFlag(QGraphicsItem.ItemIsFocusable)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
if __name__ == '__main__':
creator_window = Creator()
creator_window.ui.show()
我已经阅读了一些有关 mapFromScene 和 mapToScene 的内容,它们可以解决问题 - 但我不太了解如何使用它们。也有一些这样的例子,但我发现的都是用 C++ 编写的,我对此一无所知。因此,如果有人可以帮助我弄清楚如何解决这个问题,我将不胜感激。
您首先必须为场景设置场景矩形:
self.scene.setSceneRect(0, 0, 1000, 1000)
然后你必须将事件位置转换为场景坐标,像这样:
pos = self.canvas_area.mapToScene(event.pos())
这应该是修复您的示例所需的全部内容。
另一种可能值得考虑的方法是在场景中安装事件过滤器:
self.scene.installEventFilter(self)
然后过滤更专业的 graphics events:
def eventFilter(self, obj, event):
if obj is self.scene:
if event.type() == QtCore.QEvent.GraphicsSceneMouseDoubleClick:
self.createItems(event)
return super(Creator, self).eventFilter(obj, event)
这会创建一个 QGraphicsSceneMouseEvent, which has several useful features that a standard QMouseEvent doesn't have. This includes scenePos(),这样就不必一直映射到场景坐标,这样您就可以简单地执行以下操作:
pos = event.scenePos()