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

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

相关推荐
大学生毕业题目1 小时前
毕业项目推荐:83-基于yolov8/yolov5/yolo11的农作物杂草检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·杂草识别
凯子坚持 c3 天前
当Python遇见高德:基于PyQt与JS API构建桌面三维地形图应用实战
javascript·python·pyqt·高德地图
Goona_4 天前
pyqt+Python证件号智能校验工具
pyqt
大学生毕业题目5 天前
毕业项目推荐:52-基于yolov8/yolov5/yolo11的红绿灯检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·红绿灯检测
大学生毕业题目5 天前
毕业项目推荐:64-基于yolov8/yolov5/yolo11的蝴蝶种类检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·蝴蝶检测
大学生毕业题目6 天前
毕业项目推荐:51-基于yolov8/yolov5/yolo11的反光衣检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·反光衣检测
深兰科技7 天前
柳州市委常委、统战部部长,副市长潘展东率队首访深兰科技集团新总部,共探 AI 赋能制造大市与东盟合作新局
人工智能·beautifulsoup·numpy·pyqt·matplotlib·pygame·深兰科技
傻啦嘿哟10 天前
用PyQt快速搭建桌面应用:从零到实战的实用指南
pyqt
大学生毕业题目11 天前
毕业项目推荐:28-基于yolov8/yolov5/yolo11的电塔危险物品检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·cnn·pyqt·电塔·危险物品
Ciel_752112 天前
AmazeVault 核心功能分析,认证、安全和关键的功能
python·pyqt·pip