0
点赞
收藏
分享

微信扫一扫

QGraphicsView鼠标拖动setSceneRect失灵问题

yongxinz 2022-02-22 阅读 95
qtpython

QGraphicsView鼠标拖动setSceneRect失灵问题

问题

场景:实现放大缩小功能的同时,能够通过鼠标自由拖动。

问题:当放大时拖动异常,缩小的时候能够正常拖动

可执行版本

import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QFont, QFontMetrics
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import QRectF


class ImageView(QtWidgets.QGraphicsItem):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.__image = None

    def load_image(self, image:QtGui.QPixmap):
        self.__image = image

    def boundingRect(self) -> QtCore.QRectF:
        if self.__image is not None:
            w = self.__image.width()
            h = self.__image.height()
            return QRectF(0,0,w,h)
        else:
            return QtWidgets.QGraphicsItem.boundingRect()

    def paint(self, painter: QtGui.QPainter, option, widget) -> None:
        if self.__image is not None:
            w = self.__image.width()
            h = self.__image.height()
            painter.drawPixmap(0,0,w,h, self.__image)

class InfoItem(QtWidgets.QGraphicsItem):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.__text = "123"
        self.fm = QFontMetrics(QFont(self.__text))

    def boundingRect(self) -> QtCore.QRectF:
        self.fm.boundingRect(self.__text)
        return QtCore.QRectF(self.fm.boundingRect(self.__text))

    def updateInfo(self, pos):
        self.__text = "pos:({}, {})".format(pos.x(), pos.y())
        font = QFont(self.__text, 24)
        self.fm = QFontMetrics(font)
        self.update()

    def paint(self, painter: QtGui.QPainter, option, widget) -> None:
        if self.scene() is not None and self.__text == '123':
            self.scene().sigMouseMoved.connect(self.updateInfo, QtCore.Qt.AutoConnection)

        painter.drawText(QtCore.QPoint(0, 0), self.__text)


class Scene(QGraphicsScene):
    sigMouseMoved = QtCore.pyqtSignal(object)
    def __init__(self, parent=None):
        super().__init__(parent)

    def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
        self.sigMouseMoved.emit(event.scenePos())
        event.accept()

class View(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.startPos = None
        self.mode = 0


    def wheelEvent(self, event: QtGui.QWheelEvent) -> None:
        print(self.transform().m11())
        sensitivity = 2  # 灵敏度
        factor = event.angleDelta().y() / 240 / 5 * sensitivity + 1.0
        if self.transform().m11() > 4 and factor > 1:
            return
        self.scale(factor, factor)
        event.accept()

    def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
        self.mode = 1

    def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
        if self.mode == 1:
            delta = QtCore.QPointF(self.startPos) - event.pos()

            transform = self.transform()

            deltaX = delta.x() / transform.m11()
            deltaY = delta.y() / transform.m22()

            self.setSceneRect(self.sceneRect().translated(deltaX, deltaY))

            self.update()
        self.startPos = event.pos()
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event: QtGui.QMouseEvent) -> None:
        self.mode = 0




class sceneDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('SceneDemo')

        self.view = View(self)
        self.scene = Scene()
        self.scene.setSceneRect(QRectF(0,0,100,100))
        self.view.resize(600,600)
        self.view.setScene(self.scene)
        self.view.setDragMode(QGraphicsView.NoDrag)

        self.view.setMouseTracking(True)
        self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)


        pixItem = ImageView()
        pixItem.load_image(QtGui.QPixmap("bg.jpg"))
        self.scene.addItem(pixItem)

        info = InfoItem()
        self.scene.addItem(info)




if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    win = sceneDemo()
    win.show()

    sys.exit(app.exec())


问题一

缺少语句

self.scene.setSceneRect(QRectF(0,0,100,100))

问题二

mouseMoveEvent中判断按钮状态

# if self.mode == 1:
if event.button() == QtCore.Qt.LeftButton:
举报

相关推荐

0 条评论