我最近创建了一个程序,只要单击鼠标就会创建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()
非常感谢!
答案 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()
的鼠标事件,该事件仅返回相对于该窗口小部件的坐标。
注意:我已根据this答案更新了如何在上述代码中创建/放置项目。