Qt实现图片缩放与拖拽查看功能(附源码)

功能概述

在图像查看应用中,经常需要实现图片的缩放和拖拽查看功能。本文将介绍如何使用Qt框架实现一个支持鼠标滚轮缩放和鼠标拖拽的图片显示组件ImageZoomLabel

核心组件设计

头文件定义 (ImageZoomLabel.h)

cpp 复制代码
/**
 * @brief ImageZoomLabel 类 - 支持缩放和拖拽的图片显示标签
 * 
 * 继承自 QLabel,提供图片缩放(鼠标滚轮)和拖拽(鼠标左键)功能
 * 适用于需要查看大图或细节的场景
 */
class ImageZoomLabel : public QLabel
{
    Q_OBJECT

public:
    explicit ImageZoomLabel(QWidget *parent = nullptr);
    void setImage(const QPixmap &pixmap);
    void zoomIn();
    void zoomOut();
    void resetZoom();

signals:
    void customMouseMove(const QPoint &delta);

protected:
    void wheelEvent(QWheelEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;

private:
    QPixmap m_originalPixmap;    ///< 原始图片
    double m_scaleFactor;        ///< 缩放因子
    bool m_isDragging;           ///< 拖拽状态
    QPoint m_lastDragPos;        ///< 最后拖拽位置
    
    void updatePixmap();
};

实现文件详解 (ImageZoomLabel.cpp)

1. 构造函数初始化
cpp 复制代码
ImageZoomLabel::ImageZoomLabel(QWidget *parent)
    : QLabel(parent)
    , m_scaleFactor(1.0)        // 初始缩放因子为1.0
    , m_isDragging(false)       // 初始非拖拽状态
{
    setAlignment(Qt::AlignCenter);  // 图片居中显示
    setMinimumSize(100, 100);       // 设置最小尺寸
    setMouseTracking(true);         // 启用鼠标跟踪
}
2. 图片设置与缩放控制
cpp 复制代码
void ImageZoomLabel::setImage(const QPixmap &pixmap)
{
    m_originalPixmap = pixmap;  // 保存原始图片
    m_scaleFactor = 1.0;        // 重置缩放因子
    updatePixmap();             // 更新显示
}

void ImageZoomLabel::zoomIn()
{
    m_scaleFactor *= 1.2;       // 放大20%
    updatePixmap();
}

void ImageZoomLabel::zoomOut()
{
    m_scaleFactor /= 1.2;       // 缩小20%
    if (m_scaleFactor < 0.1) m_scaleFactor = 0.1;  // 最小缩放限制
    updatePixmap();
}
3. 鼠标滚轮事件 - 缩放功能
cpp 复制代码
void ImageZoomLabel::wheelEvent(QWheelEvent *event)
{
    if (m_originalPixmap.isNull()) return;

    // 根据滚轮方向缩放
    if (event->angleDelta().y() > 0) {
        zoomIn();    // 向上滚动放大
    } else {
        zoomOut();   // 向下滚动缩小
    }
    event->accept();  // 阻止事件传播
}
4. 鼠标事件处理 - 拖拽功能
cpp 复制代码
void ImageZoomLabel::mousePressEvent(QMouseEvent *event)
{
    // 仅当图片放大时才允许拖拽
    if (event->button() == Qt::LeftButton && m_scaleFactor > 1.0) {
        m_isDragging = true;
        m_lastDragPos = event->pos();
        setCursor(Qt::ClosedHandCursor);  // 改变光标样式
    }
    QLabel::mousePressEvent(event);
}

void ImageZoomLabel::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isDragging) {
        QPoint delta = event->pos() - m_lastDragPos;
        m_lastDragPos = event->pos();
        emit customMouseMove(delta);  // 发射拖拽信号
    }
    QLabel::mouseMoveEvent(event);
}
5. 图片更新逻辑
cpp 复制代码
void ImageZoomLabel::updatePixmap()
{
    if (m_originalPixmap.isNull()) return;

    // 计算缩放后尺寸
    QSize newSize = m_originalPixmap.size() * m_scaleFactor;
    
    // 高质量缩放图片
    QPixmap scaledPixmap = m_originalPixmap.scaled(
        newSize,
        Qt::KeepAspectRatio,        // 保持宽高比
        Qt::SmoothTransformation    // 平滑变换
    );

    setPixmap(scaledPixmap);
}

使用示例

cpp 复制代码
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include "ImageZoomLabel.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget window;
    QVBoxLayout layout(&window);

    ImageZoomLabel imageLabel;
    QPixmap pix(":/pic/image/what.jpg");  // 从资源文件加载图片
    imageLabel.setImage(pix);

    layout.addWidget(&imageLabel);
    window.resize(600, 400);
    window.show();

    return app.exec();
}
相关推荐
用户805533698031 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz5 天前
QML Hello World 入门示例
qt
xcyxiner8 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner9 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能12 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G12 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt