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: