【问题标题】:Create a QGraphicsItem at the mouse double-click position在鼠标双击位置创建一个QGraphicsItem
【发布时间】:2021-12-30 08:29:44
【问题描述】:

我正在编写一个程序,它应该在发生双击时(在场景区域内)创建一个 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++,我对此一无所知。因此,如果有人能帮我弄清楚如何解决这个问题,我将不胜感激。

【问题讨论】:

    标签: python pyqt5 mouseevent pyside2 qgraphicsview


    【解决方案1】:

    你首先必须为场景设置scene-rect:

    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,它具有标准QMouseEvent 所没有的几个有用功能。这包括scenePos(),它无需一直映射到场景坐标,让您可以简单地执行以下操作:

    pos = event.scenePos()
    

    【讨论】:

    • 非常感谢您的回答。现在我无法测试你提供的方法,但我会尽快让你知道:)
    • 嗨!我尝试了您的第一个建议,它按预期工作。谢谢你的时间:)
    • @galaxy 很高兴你发现它很有用。您现在可以将此答案标记为已接受吗?
    • 哦,我的错。现在已经接受了。
    猜你喜欢
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 2019-05-06
    • 2021-08-04
    相关资源
    最近更新 更多