QT如何通过鼠标事件实现图片的拖动和缩放

 更新时间:2024年10月11日 09:30:06   作者:笑非不退  
本文介绍了如何通过鼠标拖动移动图片以及使用鼠标滚轮进行图片缩放的技术实现,包括完整的解决方案,ImageWidget.h、ImageWidget.cpp和main.cpp的编写,以及详细的函数解释,如paintEvent()重绘图片,以及平滑缩放和偏移量的应用等,需要的朋友可以参考下

通过鼠标拖动来移动图片,并使用鼠标滚轮来缩放图片。

1、实现步骤:

1、移动图片:

使用QPoint记录图片的偏移量,当鼠标拖动时更新这个偏移量,在paintEvent()中根据偏移量绘制图片。

2、缩放图片:

使用滚轮事件调整图片的缩放倍数,在paintEvent()中重新绘制图片时应用缩放。

2、完整的解决方案:

1、ImageWidget.h

#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPixmap>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPainter>
#include <QVBoxLayout>
#include <QDebug>

class ImageWidget : public QWidget
{
    Q_OBJECT

public:
    ImageWidget(QWidget *parent = nullptr);
protected:
    // 重写paintEvent,用于绘制图片
    void paintEvent(QPaintEvent *event) override;

    // 鼠标按下事件
    void mousePressEvent(QMouseEvent *event) override;

    // 鼠标移动事件
    void mouseMoveEvent(QMouseEvent *event) override;
    // 鼠标释放事件
    void mouseReleaseEvent(QMouseEvent *event) override;
    // 滚轮事件,用于缩放图片
    void wheelEvent(QWheelEvent *event) override;

private:
    QPixmap pixmap;            // 图片
    QPoint lastMousePosition;  // 上一次鼠标点击的位置
    QPoint offset;             // 图片的偏移量
    bool isDragging;           // 标记是否正在拖动图片
    double scaleFactor;        // 缩放倍数
};

#endif // IMAGEWIDGET_H

2、ImageWidget.cpp

#include "imagewidget.h"

ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent)
{
    // 加载图片
    pixmap = QPixmap(R"(C:\Users\LiangQL\Desktop\开发者基础认证.jpg)");  // 替换成你的图片路径
    scaleFactor = 1.0;        // 初始缩放因子为1
    isDragging = false;       // 初始状态下不拖动
    offset = QPoint(0, 0);    // 图片的初始偏移为(0, 0)
}
// 重写paintEvent,用于绘制图片
void ImageWidget::paintEvent(QPaintEvent *event)
{
    // 创建一个QPainter,用于绘制图片
    QPainter painter(this);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);  // 开启平滑缩放

    // 计算缩放后的图片尺寸
    QSize scaledSize = pixmap.size() * scaleFactor;

    // 绘制图片,应用缩放和偏移量
    painter.drawPixmap(offset, pixmap.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

// 鼠标按下事件
void ImageWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        isDragging = true;                // 开始拖动
        lastMousePosition = event->pos(); // 记录鼠标点击位置
    }
}

// 鼠标移动事件
void ImageWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (isDragging) {
        // 计算鼠标的移动距离
        QPoint delta = event->pos() - lastMousePosition;

        // 更新图片的偏移量
        offset += delta;

        // 更新鼠标位置
        lastMousePosition = event->pos();

        // 触发重新绘制
        update();
    }
}

// 鼠标释放事件
void ImageWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        isDragging = false;  // 结束拖动
    }
}

// 滚轮事件,用于缩放图片
void ImageWidget::wheelEvent(QWheelEvent *event)
{
    // 滚轮向上放大,向下缩小
    if (event->angleDelta().y() > 0) {
        scaleFactor *= 1.1;  // 放大
    } else {
        scaleFactor /= 1.1;  // 缩小
    }

    // 限制缩放范围
    scaleFactor = qBound(0.1, scaleFactor, 10.0);

    // 更新显示
    update();
}

3、 调用main.cpp

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPixmap>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPainter>
#include <QVBoxLayout>
#include <QDebug>
#include "ImageWidget.h"

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

    // 创建主窗口
    QWidget window;
    window.setFixedSize(800, 600);  // 设置窗口大小

    // 创建图片控件(自定义的类)
    ImageWidget *imageWidget = new ImageWidget;

    // 使用布局管理器将图片控件放置在窗口中
    QVBoxLayout *layout = new QVBoxLayout(&window);
    layout->addWidget(imageWidget);

    // 显示主窗口
    window.show();

    return app.exec();
}

3、详细解释:

1. paintEvent() 重绘图片:

paintEvent()方法用于自定义控件的绘制。在这个方法中,我们使用QPainter对象来绘制图片。
pixmap.scaled():使用pixmap.scaled()方法来缩放图片,根据scaleFactor缩放图片并保持其宽高比。
painter.drawPixmap(offset, ...):在指定的偏移量位置绘制图片,offset表示图片在控件中的偏移。

2. 图片移动:

mousePressEvent():当鼠标左键按下时,记录鼠标点击位置,并开始拖动图片(isDragging = true)。
mouseMoveEvent():如果正在拖动图片(isDragging为true),则计算鼠标的移动距离,将图片的offset偏移量更新为原来的偏移量加上鼠标移动的距离。
mouseReleaseEvent():当鼠标左键释放时,结束拖动(isDragging = false)。

3. 图片缩放:

wheelEvent():处理鼠标滚轮事件。滚轮向上时,放大图片;滚轮向下时,缩小图片。
scaleFactor *= 1.1:每次滚动时,缩放倍数按10%变化。
qBound(0.1, scaleFactor, 10.0):限制缩放比例在0.1到10倍之间,防止图片缩得太小或放得太大。

4. 平滑缩放:

Qt::SmoothTransformation:使用平滑缩放算法,防止图片缩放后出现锯齿。

5. 偏移量的作用:

offset用于记录图片相对于窗口的偏移量,当鼠标拖动时,更新这个偏移量。
在paintEvent()中,每次绘制时都使用这个偏移量来控制图片的位置。
运行效果:
拖动图片:按住鼠标左键并移动,可以看到图片在窗口内部移动。
缩放图片:滚动鼠标滚轮,图片会放大或缩小,同时保持宽高比。

总结

到此这篇关于QT如何通过鼠标事件实现图片的拖动和缩放的文章就介绍到这了,更多相关QT鼠标事件实现图片拖动缩放内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++中默认无参构造函数的工作机制浅析

    C++中默认无参构造函数的工作机制浅析

    构造函数主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用;析构函数主要作用在于对象销毁前系统自动调用,执行一些清理工作
    2023-02-02
  • C语言实现密码程序

    C语言实现密码程序

    这篇文章主要为大家详细介绍了C语言实现密码程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • C语言可变参数列表的用法与深度剖析

    C语言可变参数列表的用法与深度剖析

    这篇文章主要给大家介绍了关于C语言可变参数列表的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • 详解如何配置CLion作为Qt5开发环境的方法

    详解如何配置CLion作为Qt5开发环境的方法

    这篇文章主要介绍了详解如何配置CLion作为Qt5开发环境的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 使用C语言实现扫雷游戏

    使用C语言实现扫雷游戏

    这篇文章主要为大家详细介绍了使用C语言实现扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++核心编程之内存分区详解

    C++核心编程之内存分区详解

    这篇文章主要为大家详细介绍了C++核心编程之内存分区,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C++ vector扩容解析noexcept应用场景

    C++ vector扩容解析noexcept应用场景

    这篇文章主要介绍了C++ vector扩容解析noexcept应用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • 利用C++11原子量如何实现自旋锁详解

    利用C++11原子量如何实现自旋锁详解

    当自旋锁尝试获取锁时以忙等待(busy waiting)的形式不断地循环检查锁是否可用,下面这篇文章主要给大家介绍了关于利用C++11原子量如何实现自旋锁的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-06-06
  • C++标准模板库string类的介绍与使用讲解

    C++标准模板库string类的介绍与使用讲解

    今天小编就为大家分享一篇关于C++标准模板库string类的介绍与使用讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 详解C++之函数重载

    详解C++之函数重载

    这篇文章主要介绍了c++函数重载的相关知识,文章讲解的非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06

最新评论