pyqt QGraphicsView 以鼠标为中心进行缩放

注意几个关键点:

  1. 初始化
python 复制代码
class CustomGraphicsView(QGraphicsView):
    def __init__(self, parent=None):
        super(CustomGraphicsView, self).__init__(parent)
        self.scene = QGraphicsScene()
        self.setScene(self.scene)
        self.setGeometry(0, 0, 1024, 600)

        # 以下初始化代码较为重要
        self.setMouseTracking(True)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)   # 按需开启
        # self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)   # 按需开启     
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        
  1. 关键实现函数:重定义滚轮缩放事件(可能会达不到预期效果,请看步骤3或确认初始化)
python 复制代码
def wheelEvent(self, event: QWheelEvent) -> None:
        if event.modifiers() == Qt.ControlModifier:
            mouse_pos = event.pos()
            scene_pos = self.mapToScene(mouse_pos) #缩放前鼠标在scene的位置

            s = 1.2 #按需调整

            if(event.angleDelta().y() > 0):
                self.scale(s,s)
            else:
                self.scale(1/s,1/s)

            view_point = self.mapFromScene(scene_pos) #缩放后原scene进行映射新鼠标位置
            self.verticalScrollBar().setValue(int(view_point.y()-mouse_pos.y())) #通过滚动条进行移动视图
            self.horizontalScrollBar().setValue(int(view_point.x()-mouse_pos.x()))
            return 
        else:
            return super().wheelEvent(event) # 保证滚动条能滚动
  1. 如果未到达预期效果,可能还需重写所有鼠标事件:
python 复制代码
def mousePressEvent(self, event: QMouseEvent) -> None:
        if event.button() == Qt.LeftButton:
            self.dragStartPos = event.pos() #用于鼠标拖拽视图
        return
python 复制代码
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
        pass
        return
python 复制代码
def mouseMoveEvent(self, event):
        if event.buttons() and Qt.LeftButton: # 实现鼠标拖拽视图
            newpos = event.pos()
            delta = newpos - self.dragStartPos
            self.dragStartPos = newpos
            
            self.verticalScrollBar().setValue(self.verticalScrollBar().value() - delta.y())
            self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - delta.x())
        return

仅此记录,未重定义鼠标所有事件导致了近半个月的苦恼,虽然修复了但是仍不知道什么原因

相关推荐
深蓝海拓8 小时前
PySide6从0开始学习的笔记(八) 控件(Widget)之QSlider(滑动条)
笔记·python·qt·学习·pyqt
深蓝海拓1 天前
PySide6从0开始学习的笔记(二) 控件(Widget)之容器类控件
笔记·qt·学习·pyqt
叶子丶苏1 天前
第十七节_PySide6基本窗口控件深度补充_窗口绘图类(QPicture类) 下篇
python·pyqt
深蓝海拓1 天前
PySide6从0开始学习的笔记(六) 控件(Widget)之按钮类
笔记·python·qt·学习·pyqt
深蓝海拓1 天前
PySide6从0开始学习的笔记(七) 控件(Widget)之文字输入类控件
笔记·python·qt·学习·pyqt
python开发笔记1 天前
PyQt(12)TreeWidget与TreeView对比
pyqt
Java Fans2 天前
PyQt多页面切换教程
pyqt
深蓝海拓2 天前
PySide6从0开始学习的笔记(五) 信号与槽
笔记·qt·学习·pyqt
深蓝海拓3 天前
PySide6从0开始学习的笔记(四)QMainWindow
笔记·python·学习·pyqt
深蓝海拓3 天前
PySide6 的 QSettings简单应用学习笔记
python·学习·pyqt