Проблема вызвана тем, что вы отправляете события QGraphicsView
на QGraphicsObject
. В случае QGraphicsView
событие имеет тип QMouseEvent
, но в случае QGraphicsObject
оно имеет тип QGraphicsSceneMouseEvent
. В заключение, вы не должны передавать события QGraphicsView
в QGraphicsObject
, поскольку они относятся к разным событиям с различной информацией.
Событие mousePressEvent
включено по умолчанию, но в случае события mouseMoveEvent
оно не может быть обработано QGraphicsObject
, вместо этого вы должны использовать hoverMoveEvent
, но они будут работать только внутри boundingRect
QGraphicsObject
.
#!/usr/bin/env python
from PyQt5.QtCore import (QRectF)
from PyQt5.QtGui import (QPainter, QPixmap)
from PyQt5.QtWidgets import (QMainWindow, QApplication, QGraphicsObject, QGraphicsView, QGraphicsScene)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.mypixmap = QPixmap("exit1.png")
self.setAcceptHoverEvents(True)
def paint(self, painter, option, widget):
painter.setOpacity(1)
painter.drawPixmap(0,0, 512, 512, self.mypixmap)
painter.drawLine(2,2,20,20)
def boundingRect(self):
return QRectF(0,0,512, 512)
def hoverMoveEvent(self, event):
print("ccccccccccc ", event.pos())
def mousePressEvent(self, event):
print("bbbbbbbbbbbb", event.pos())
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.scene = QGraphicsScene(self)
self.tic_tac_toe = TicTacToe(self)
self.myScale = 2
self.tic_tac_toe.setScale(self.myScale)
self.setScene(self.scene)
self.scene.addItem(self.tic_tac_toe)
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Example()
w.show()
sys.exit(app.exec_())
С другой стороны, эти точки не совпадают с положением на сцене, поскольку эти координаты относятся к элементу.
Чтобы вы могли лучше понять, мы могли бы использовать следующую аналогию, скажем, вы записываете сцену с помощью камеры, экран камеры похож на QGraphicsView
, сцена - QGraphicsScene
, а актеры - QGraphicsItem
s и QGraphicsObject
s. Каждый из этих элементов имеет свою систему координат.
В случае QGraphicsView
ваш QMouseEvent
возвращает координаты в единицах пикселей, если вы хотите преобразовать его в координаты сцены, вы должны использовать mapToScene()
.
В случае, если QGraphicsItem
/ QGraphicsObject
имеют координаты, отличные от координат сцены, на них не влияют такие преобразования, как масштаб, вращение и т. Д. Это то, что печатается в предыдущем примере. Если вы хотите преобразовать его в единицы сцены, вы должны использовать mapToScene()
.
В следующем примере я показываю все впечатления в единицах сцены.
#!/usr/bin/env python
from PyQt5.QtCore import (QRectF)
from PyQt5.QtGui import (QPainter, QPixmap)
from PyQt5.QtWidgets import (QMainWindow, QApplication, QGraphicsObject, QGraphicsView, QGraphicsScene)
class TicTacToe(QGraphicsObject):
def __init__(self, helper):
super(TicTacToe, self).__init__()
self.mypixmap = QPixmap("exit1.png")
self.setAcceptHoverEvents(True)
def paint(self, painter, option, widget):
painter.setOpacity(1)
painter.drawPixmap(0,0, 512, 512, self.mypixmap)
painter.drawLine(2,2,20,20)
def boundingRect(self):
return QRectF(0,0,512, 512)
def hoverMoveEvent(self, event):
#print("hoverMoveEvent ", event.pos())
print("hoverMoveEvent", self.mapToScene(event.pos()))
def mousePressEvent(self, event):
#print("mousePressEvent", event.pos())
print("mousePressEvent", self.mapToScene(event.pos()))
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.scene = QGraphicsScene(self)
self.setMouseTracking(True)
self.tic_tac_toe = TicTacToe(self)
self.myScale = 2
self.tic_tac_toe.setScale(self.myScale)
self.setScene(self.scene)
self.scene.addItem(self.tic_tac_toe)
def mouseMoveEvent(self, event):
print("mouseMoveEvent", self.mapToScene(event.pos()))
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.y = MyGraphicsView()
self.setCentralWidget(self.y)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Example()
w.show()
sys.exit(app.exec_())
Если вам нужна дополнительная информация, проверьте следующие ссылки: