Qgraphicsview项目未放置在

时间:2015-06-17 17:53:07

标签: python mouseevent pyqt4 qgraphicsscene

我最近创建了一个程序,只要单击鼠标就会创建QgraphicsEllipseItems。那部分有效!但是,它不在我的光标所在的确切位置。它似乎比我的鼠标光标略高。我确实创建了一个QGraphicsRectItem,所以这两个项目可能会相互冲突并相互移动?如何将这些圆圈放在矩形项目的顶部?这是代码

class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        self.scene = QtGui.QGraphicsScene(self)
        self.item = QtGui.QGraphicsRectItem(400, 400, 400, 400)
        self.scene.addItem(self.item)
        self.setScene(self.scene)
    def paintMarkers(self):
        self.cursor = QtGui.QCursor()
        self.x = self.cursor.pos().x()
        self.y = self.cursor.pos().y()
        self.circleItem = QtGui.QGraphicsEllipseItem(self.x,self.y,10,10)
        self.scene.addItem(self.circleItem)
        self.circleItem.setPen(QtGui.QPen(QtCore.Qt.red, 1.5))
        self.setScene(self.scene)

class Window(QtGui.QMainWindow):
    def __init__(self):
        #This initializes the main window or form
        super(Window,self).__init__()
        self.setGeometry(50,50,1000,1000)
        self.setWindowTitle("Pre-Alignment system")

        self.view = MyView()
        self.setCentralWidget(self.view)
    def mousePressEvent(self,QMouseEvent):
        self.view.paintMarkers()

非常感谢!

1 个答案:

答案 0 :(得分:1)

用于放置QGraphics...Item的坐标存在两个问题。第一个是QCursor的坐标为global screen coordinates,因此您需要使用self.mapFromGlobal()将它们转换为相对于QGraphicsView的坐标。

其次,您实际上想要相对于当前QGraphicsScene的坐标,因为这是您绘制项目的位置。这是因为场景可以从视图偏移(例如,在比视图大的场景周围平移)。为此,请在相对于QGraphicsView的坐标上使用self.mapToScene()

我想指出,通常你会在QGraphicsScene上绘制一些内容,以响应QGraphicsView中的某种鼠标事件,这需要重新实现QGraphicsView.mouseMoveEvent或{{1}等内容}}。这些事件处理程序传递QGraphicsView.mousePressEvent,其中包含相对于视图的鼠标坐标,因此您不需要执行我在第一段中提到的全局坐标转换。

更新

我刚看到你的other问题,现在了解一些问题好一点。您不应该在主窗口中覆盖鼠标事件。而是在视图中覆盖它。例如:

QEvent

这里我们不需要使用class MyView(QtGui.QGraphicsView): def __init__(self): QtGui.QGraphicsView.__init__(self) self.scene = QtGui.QGraphicsScene(self) self.item = QtGui.QGraphicsRectItem(400, 400, 400, 400) self.scene.addItem(self.item) self.setScene(self.scene) def paintMarkers(self, event): # event position is in coordinates relative to the view # so convert them to scene coordinates p = self.mapToScene(event.x(), event.y()) self.circleItem = QtGui.QGraphicsEllipseItem(0,0,10,10) self.circleItem.setPos(p.x()-self.circleItem.boundingRect().width()/2.0, p.y()-self.circleItem.boundingRect().height()/2.0) self.scene.addItem(self.circleItem) self.circleItem.setPen(QtGui.QPen(QtCore.Qt.red, 1.5)) # self.setScene(self.scene) # <-- this line should not be needed here # Note, I've renamed the second argument `event`. Otherwise you locally override the QMouseEvent class def mousePressEvent(self, event): self.paintMarkers(event) # you may want to preserve the default mouse press behaviour, # in which case call the following return QGraphicsView.mousePressEvent(self, event) (我在第一段中介绍的内容),因为我们使用来自QWidget.mapFromGlobal()的鼠标事件,该事件仅返回相对于该窗口小部件的坐标。

更新2

注意:我已根据this答案更新了如何在上述代码中创建/放置项目。