Положение мыши в mouseMoveEvent и mousePressEvent различается: QGraphicsObject

Положение мыши в mouseMoveEvent и mousePressEvent в следующем примере различается. Это происходит из-за добавленного масштабирования. Без масштабирования позиции такие же.

Нужно ли мне обновлять boundingRect в соответствии с измененным масштабированием? Как?

#!/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")

    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 keyPressEvent(self, event):
        print "aaaaaaaaaa"

    def mouseMoveEvent(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)
        self.setMouseTracking(True) 

    def keyPressEvent(self, event):
        self.tic_tac_toe.keyPressEvent(event)

    def mouseMoveEvent(self, event):
        print "mouse"        
        self.tic_tac_toe.mouseMoveEvent(event)


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_())
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
1 329
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема вызвана тем, что вы отправляете события QGraphicsView на QGraphicsObject. В случае QGraphicsView событие относится к типу QMouseEvent, а в случае QGraphicsObject - к типу QGraphicsSceneMouseEvent. В заключение, вы не должны передавать события QGraphicsView в QGraphicsObject, поскольку они относятся к разным событиям с разной информацией.

Событие mousePressEvent включено по умолчанию, но в случае события mouseMoveEvent оно не может быть обработано QGraphicsObject, вместо этого вы должны использовать hoverMoveEvent, но они будут работать только внутри boundingRectQGraphicsObject.

#!/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 и QGraphicsObject. Каждый из этих элементов имеет свою систему координат.

В случае 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_())

Если вам нужна дополнительная информация, проверьте следующие ссылки:

Я вам безмерно благодарен. Прошу вас показать документацию, где все это упоминается, чтобы я тоже мог узнать. Спасибо.

Aquarius_Girl 02.05.2018 08:33

@Aquarius_Girl Я добавлю больше информации через несколько минут.

eyllanesc 02.05.2018 08:34

Другие вопросы по теме