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

news/2024/12/21 22:33:30/

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

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_OBJECTpublic: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;        // 初始缩放因子为1isDragging = 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()中,每次绘制时都使用这个偏移量来控制图片的位置。
运行效果:
拖动图片:按住鼠标左键并移动,可以看到图片在窗口内部移动。
缩放图片:滚动鼠标滚轮,图片会放大或缩小,同时保持宽高比。

http://www.ppmy.cn/news/1536715.html

相关文章

【网络安全】学过编程就是黑客?

前言 黑客&#xff0c;相信经常接触电脑的朋友们对这个词都不陌生&#xff0c;各类影视视频中黑客总是身处暗处&#xff0c;运筹帷幄&#xff0c;正是这种神秘感让我走向学习编程的道路&#xff0c;也正是如此让我明白黑客远没有我想象中那么“帅气”。 黑客 &#x1f4bb; 黑…

本地访问autodl的jupyter notebook

建立环境并安装jupyter conda create --name medkg python3.10 source activate medkg pip install jupyter 安装完成后&#xff0c;输入jupyter notebook --generate-config 输入ipython,进入python In [2]: from jupyter_server.auth import passwd In [3]: passwd(algori…

常见的负载均衡

1.常见的负载均衡服务 负载均衡服务是分布式系统中用于分配网络流量和请求的关键组件&#xff0c;它可以帮助提高应用程序的可用性、可扩展性和响应速度。以下是一些常用的负载均衡服务&#xff1a; Nginx&#xff1a;一个高性能的Web服务器和反向代理&#xff0c;广泛用于实现…

外国钞票面值检测系统源码分享[一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

外国钞票面值检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

钰泰ETA6096移动电源IC

描述 ETA6986 是一款开关锂离子电池充电器&#xff0c;能够为电池提供高达 5A 的充电电流&#xff0c;并在升压 OTG 操作中提供高达 3A 的电流。它采用电荷泵来实现非常快速的输入 OVP&#xff0c;对于充电&#xff0c;它使用专有的控制方案&#xff0c;无需电流感应电阻器即可…

CSID-GAN:基于生成对抗网络的定制风格室内平面设计框架论文阅读

CSID-GAN: A Customized Style Interior Floor Plan Design Framework Based on Generative Adversarial Network 摘要前言II. CSID-GAN METHODA. Overall FrameworkB. Algorithm and Loss Function III. DATASETS AND EVALUATION METRICSA. DatasetsB. Evaluation Metrics IV.…

【秋招笔试】10.08华为荣耀秋招(已改编)-(第二套)题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 本次的三题全部上线…

毕设 深度学习语义分割实现弹幕防遮(源码分享)

文章目录 0 简介1 课题背景2 技术原理和方法2.1基本原理2.2 技术选型和方法 3 实例分割4 实现效果最后 0 简介 今天学长向大家分享一个毕业设计项目 毕业设计 深度学习语义分割实现弹幕防遮(源码分享) &#x1f9ff; 项目分享:见文末! 1 课题背景 弹幕是显示在视频上的评论…