C++基于QWidget和QLabel实现图片缩放,拉伸与拖拽

 更新时间:2024年02月28日 10:26:30   作者:随性随笔  
这篇文章主要为大家详细介绍了C++如何基于QWidget和QLabel实现图片缩放、拉伸与拖拽等功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

最近做ffmpeg视频拉流解码,涉及到截图功能的图片显示操作,特此做记录。

头文件

#ifndef QPICTURESHOT_H
#define QPICTURESHOT_H
 
#include <QWidget>
#include <QLabel>
 
class QPictureShot : public QWidget
{
    Q_OBJECT
 
public:
    explicit QPictureShot(QWidget *parent = nullptr);
 
    ~QPictureShot();
 
 
    //接收一张图片文件路径
    void inputPicFile(QString sFile);
 
    //设置定时消失
    void setAutoDismiss(int nShowSeconds);
 
protected:
 
private:
    //初始化窗体部件
    void InitLayout();
 
    void wheelEvent(QWheelEvent * event) override;
    void resizeEvent(QResizeEvent* event) override ;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
 
    QLabel *m_pPicLabel;    //图片
    QImage m_image;
    QRect m_initRect;
 
    double opacityValue;//窗体初始化透明度
    float ratio = 1.0f;
    bool m_bLeftPress;//左键按下
    float m_difX;
    float m_difY;
 
 
};
 
#endif // QPICTURESHOT_H

cpp文件:

#include "qpictureshot.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QPainter>
#include <QTimer>
#include <QMouseEvent>
#include <QDebug>
 
 
#ifdef WIN32
#pragma execution_character_set("utf-8")
#endif
 
QPictureShot::QPictureShot(QWidget *parent):
    QWidget(parent),
    m_pPicLabel(new QLabel(this)),
    opacityValue(1.0)
{
    setWindowFlags(Qt::Window  |Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint);
    setWindowTitle("图片");
    this->setAttribute(Qt::WA_TranslucentBackground);
    InitLayout();
}
 
 
QPictureShot::~QPictureShot()
{
 
}
 
 
//接收一张图片文件路径
void QPictureShot::inputPicFile(QString sFile)
{
    int nPos = sFile.lastIndexOf("/");
    QString sText = sFile.right(sFile.length() - nPos - 1);
    setWindowTitle(sText);
 
    m_image = QImage(sFile);
    if (m_image.isNull())
    {
        m_pPicLabel->setStyleSheet("font-size:18pt;color:white;");
        m_pPicLabel->setAlignment(Qt::AlignCenter);
        m_pPicLabel->setText("文件不存在");
    }
    else
    {
        QPixmap pix = QPixmap::fromImage(m_image);
        pix = pix.scaled(m_pPicLabel->width(), m_pPicLabel->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
 
        m_pPicLabel->setScaledContents(true);
        m_pPicLabel->setPixmap(pix);
    }
 
}
 
//设置定时消失
void QPictureShot::setAutoDismiss(int nShowSeconds)
{
    QTimer *mtimer = new QTimer(this);//隐藏的定时器
    mtimer->setTimerType(Qt::PreciseTimer);
    connect(mtimer,&QTimer::timeout,this,[=](){
        if(opacityValue<=0){ this->close(); }
        opacityValue = opacityValue-0.1;
        this->setWindowOpacity(opacityValue);    //设置窗口透明度
        });
 
 
    QTimer *mShowtimer = new QTimer(this);//显示时间的定时器
    mShowtimer->setTimerType(Qt::PreciseTimer);// 修改定时器对象的精度
    connect(mShowtimer,&QTimer::timeout,this,[=](){
        mtimer->start(100);//执行延时自动关闭
        });
    mShowtimer->start(nShowSeconds);
}
//初始化窗体部件
void QPictureShot::InitLayout()
{
    //设置部件大小
    QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以
    this->resize(desktop->width() * 0.8, desktop->height() * 0.8);
    m_pPicLabel->setGeometry(0, 0, desktop->width() * 0.8, desktop->height() * 0.8);
    m_pPicLabel->setCursor(QCursor(Qt::PointingHandCursor));
    m_initRect = this->rect();
 
}
 
void QPictureShot::wheelEvent(QWheelEvent * event)
{ 
    if (m_image.isNull()) return;
 
    QPoint numDegrees = event->angleDelta() / 120;
    float ratio_temp =  (1 + numDegrees.y() / 20.0);
    ratio *= ratio_temp;//在当前的比例基础上乘以
    if (ratio > 3 || ratio < 0.05) return;
 
    int w = ratio_temp*m_pPicLabel->width(); //显示宽度
    int h = ratio_temp*m_pPicLabel->height(); //显示高度
 
    QPoint mousePos = event->pos();
    QPoint picPos = m_pPicLabel->pos();
    int pageWidth = mousePos.x() - picPos.x();
    int pageHeight = mousePos.y() - picPos.y();
 
 
    QPixmap pix = QPixmap::fromImage(m_image);
    pix = pix.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); //图像缩放到指定高度和宽度,保持长宽比例
 
    m_pPicLabel->setScaledContents(true);
    m_pPicLabel->setPixmap(pix);
 
    int nMoveX =  pageWidth * (numDegrees.y() / 20.0);
    int nMoveY =  pageHeight * (numDegrees.y() / 20.0);
    m_pPicLabel->setGeometry(m_pPicLabel->pos().x() - nMoveX, m_pPicLabel->pos().y() - nMoveY, w, h);
 
 
}
 
void QPictureShot::mousePressEvent(QMouseEvent *event)
{
    if(event->buttons() & Qt::LeftButton)
    {
        m_bLeftPress = true;
        m_difX = event->pos().x() - m_pPicLabel->x();
        m_difY = event->pos().y() - m_pPicLabel->y();
    }
}
void QPictureShot::mouseMoveEvent(QMouseEvent *event)
{
    if (m_bLeftPress)
    {
        int x = event->pos().x() - m_difX;
        int y = event->pos().y() - m_difY;
        m_pPicLabel->move(x, y);
    }
}
void QPictureShot::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    m_bLeftPress = false;
}
 
 
 
void QPictureShot::resizeEvent(QResizeEvent* event) {
    // 在此处添加对窗口拉伸事件的处理逻辑
    // 输出新的大小信息
    qDebug("New size: %dx%d", width(), height());
 
    float x_ratio = width() * 1.0 / m_initRect.width();
    float y_ratio = height() * 1.0 / m_initRect.height();
 
    m_pPicLabel->setGeometry(m_pPicLabel->x() * x_ratio, m_pPicLabel->y() * y_ratio,  m_pPicLabel->width() * x_ratio, m_pPicLabel->height() * y_ratio);
    if (!m_image.isNull())
    { 
        QPixmap pix = QPixmap::fromImage(m_image);
        pix = pix.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
 
        m_pPicLabel->setScaledContents(true);
        m_pPicLabel->setPixmap(pix);
    }
 
    m_initRect = this->rect();
    // 调用基类的resizeEvent()函数,确保默认行为也得到执行
    QWidget::resizeEvent(event);
}

测试入口代码

QPictureShot *pic = new QPictureShot(this);
    pic->inputPicFile(":/bg.png");
    pic->show();

到此这篇关于C++基于QWidget和QLabel实现图片缩放,拉伸与拖拽的文章就介绍到这了,更多相关C++图片缩放拉伸与拖拽内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • QT5实现UDP通信的示例代码

    QT5实现UDP通信的示例代码

    本文主要介绍了QT5实现UDP通信的示例代码,主要使用QUdpSocket类用于实现UDP通信,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C语言函数指针详解

    C语言函数指针详解

    大家好,本篇文章主要讲的是C语言函数指针详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • 深入了解c++11 移动语义与右值引用

    深入了解c++11 移动语义与右值引用

    这篇文章主要介绍了c++ 移动语义与右值引用的相关资料,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08
  • c++中std::placeholders的使用方法

    c++中std::placeholders的使用方法

    std::placeholders 是 C++ 标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • C++11实现简易定时器的示例代码

    C++11实现简易定时器的示例代码

    这篇文章主要介绍了C++11实现简易定时器的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 使用VC++实现打印乘法口诀表

    使用VC++实现打印乘法口诀表

    本文给大家分享的是一个超级简单的小例子,使用vc++打印乘法口诀表,给需要的小伙伴参考下吧。
    2015-03-03
  • C++之list的使用与模拟实现过程

    C++之list的使用与模拟实现过程

    本文简述C++ list容器,其基于双向循环链表,支持高效插入删除,迭代器失效仅影响被删除节点,模拟实现时通过封装节点和迭代器,对比list与vector的特性差异,如随机访问、空间利用率及适用场景
    2025-10-10
  • 深入剖析Android中init进程实现的C语言源码

    深入剖析Android中init进程实现的C语言源码

    这篇文章主要介绍了Android中init进程实现的C语言源码,init属性服务在安卓中属于系统的底层Linux服务,需要的朋友可以参考下
    2015-07-07
  • qt首次连接MYSQL驱动的各种问题图文详解

    qt首次连接MYSQL驱动的各种问题图文详解

    通常来说,我们对数据库的操作更多地在于对数据库表的操作,下面这篇文章主要给大家介绍了关于qt首次连接MYSQL驱动的各种问题,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04
  • VC++ loadlibrary()加载三方dll失败, 返回错误码:126的解决方法

    VC++ loadlibrary()加载三方dll失败, 返回错误码:126的解决方法

    今天在编写VC++ loadlibrary()加载三方dll是总是失败,并且返回错误码:126,这里就为大家分享一下具体的解决方法
    2021-03-03

最新评论