QT QLabel加载图片等比全屏自适应屏幕大小显示

news/2025/2/21 4:52:39

最近在工作项目中,遇到一个需求:

1.使用QLabel显示一张图片;

2.当点击这个QLabel时,需要全屏显示;但不能改变原来的尺寸;

3.当点击放大后的QLabel时,恢复原有大小.

于是乎,就有了本篇博客,介绍如何实现这样的功能.

一、演示效果

在一个水平布局中,添加两个Lable用于显示图片,两张图片的尺寸不一样;

当点击图片时,全屏显示当前图片,再次点击时,恢复;

二、编码过程

1.自定义类继承自QLabel

实现功能,是的Label拥有鼠标点击触发信号功能

labelclicked.h

#ifndef LABEL_CLICKED_H
#define LABEL_CLICKED_H

#include <QLabel>
#include <QMouseEvent>

class LabelClicked : public QLabel {
    Q_OBJECT
public:
    explicit LabelClicked(QWidget *parent = nullptr);
    ~LabelClicked() override;


    /**
     * @brief 将参数内容转换为QPixmap保存,后通过点击信号发射出去
     * @param byte  图片字节数据
     */
    void setImageByteData(QByteArray byte);
    /**
     * @brief 将参数内容转换为QPixmap保存,后通过点击信息发射出去
     * @param image 图片
     */
    void setImage(QImage image);

signals:
    /// 鼠标左键单击信号
    void SignalLabelClicked();
    /// 鼠标左键单击信号,参数是设置保存的图片
    void SignalLabelImageClicked(const QPixmap &pixmap);

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

private:
    QPixmap m_pixmap;       /// 保存图片,图片被点击时通过信号发送出去
};

#endif // LABEL_CLICKED_H

 

labelclicked.cpp

#include "labelclicked.h"

#include <QToolTip>
#include <QPainter>


LabelClicked::LabelClicked(QWidget *parent) : QLabel(parent)
{

}

LabelClicked::~LabelClicked()
{

}

void LabelClicked::setImageByteData(QByteArray byte)
{
    QImage image;
    if (image.loadFromData(byte)) {
        this->m_pixmap = QPixmap::fromImage(image);
    } else {
        this->m_pixmap = QPixmap();
    }
}

void LabelClicked::setImage(QImage image)
{
    this->m_pixmap = QPixmap::fromImage(image);
    update();
}

void LabelClicked::mousePressEvent(QMouseEvent *event)
{
    if (Qt::LeftButton == event->button()) {
        // 发射点击信号
        emit SignalLabelImageClicked(this->m_pixmap);
    }

    QLabel::mousePressEvent(event);
}

void LabelClicked::mouseReleaseEvent(QMouseEvent *event)
{
    if (Qt::LeftButton == event->button()) {
        emit SignalLabelClicked();
    }

    QLabel::mouseReleaseEvent(event);
}

2.布局

在主页面中,拖一个水平布局出来,方便添加Lable部件展示图片

3.编码

1) 定义两个Label,并添加到布局中

使用自定义的 LabelClicked 创建

LabelClicked *pLabelImage1 = new LabelClicked(this);
LabelClicked *pLabelImage2 = new LabelClicked(this);
ui->horizontalLayout->addWidget(pLabelImage1);
ui->horizontalLayout->addWidget(pLabelImage2);

2) 给每一个 Lable 设置大小和图片,并绑定信号和槽函数

pLabelImage1->setFixedSize(130, 70);
QImage image1("111.png", "png");
pLabelImage1->setPixmap(QPixmap::fromImage(image1).scaled(pLabelImage1->width(), pLabelImage1->height()));
pLabelImage1->setScaledContents(true);
// 自定义方法,保存一下iamge,当点击信号触发时,将该图片发射出去
pLabelImage1->setImage(image1);
connect(pLabelImage1, &LabelClicked::SignalLabelImageClicked, this, &Widget::onHandleWatchImage);


pLabelImage2->setFixedSize(130, 70);
QImage image2("222.png", "png");
pLabelImage2->setPixmap(QPixmap::fromImage(image2).scaled(pLabelImage2->width(), pLabelImage2->height()));
pLabelImage2->setScaledContents(true);
// 自定义方法,保存一下iamge,当点击信号触发时,将该图片发射出去
pLabelImage2->setImage(image2);
connect(pLabelImage2, &LabelClicked::SignalLabelImageClicked, this, &Widget::onHandleWatchImage);

到这一步,编译运行,效果如下:

图片已经成功加载到布局中,并且显示出来;

3) 处理点击全屏显示

定义槽函数

void Widget::onHandleWatchImage(const QPixmap &pixmap) { }

实现如下代码:

通过QDialog进行全屏显示

void Widget::onHandleWatchImage(const QPixmap &pixmap)
{
    QDialog dialog;
    LabelClicked maxLabel(&dialog);
    maxLabel.setImage(pixmap.toImage());
    connect(&maxLabel, &LabelClicked::SignalLabelClicked, [&] {
        dialog.close();
    });


    // 获取屏幕分辨率
    QScreen *screen = QGuiApplication::primaryScreen();
    QRect screenGeometry = screen->geometry();
    int screenWidth = screenGeometry.width();
    int screenHeight = screenGeometry.height();

    // 获取图片原始尺寸
    int imageWidth = pixmap.width();
    int imageHeight = pixmap.height();

    // 计算等比缩放的尺寸
    qreal scaleFactor = qMin(static_cast<qreal>(screenWidth) / imageWidth,
                             static_cast<qreal>(screenHeight) / imageHeight);
    int scaledWidth = static_cast<int>(imageWidth * scaleFactor);
    int scaledHeight = static_cast<int>(imageHeight * scaleFactor);

    // 创建缩放后的QPixmap对象
    QPixmap scaledPixmap = pixmap.scaled(scaledWidth, scaledHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);

    // 设置图片大小
    maxLabel.setScaledContents(true);
    maxLabel.setPixmap(scaledPixmap);
    maxLabel.setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // 让label根据内容调整大小
    maxLabel.adjustSize(); // 根据内容调整label的大小

    // 居中
    int w = (screenWidth - scaledWidth) / 2;
    int h = (screenHeight - scaledHeight) / 2;
    maxLabel.move(w, h);

    // 最大化和无边框
    dialog.setWindowFlag(Qt::FramelessWindowHint);
    dialog.setWindowFlag(Qt::WindowStaysOnTopHint);
    dialog.setWindowState(dialog.windowState() | Qt::WindowFullScreen);

    dialog.exec();
}

到此,已经处理完毕,编译运行即可!


http://www.niftyadmin.cn/n/5860175.html

相关文章

挑战一星期复现一个项目——安全帽项目

本项目为识别安全帽项目&#xff0c;基于yoloV5模型&#xff0c;接下来&#xff0c;我将一步一步展示我的完整复现过程以及遇到的问题和解决方案。 前言 我们在利用GPU进行深度学习的时候&#xff0c;都要去NVIDIA的官网下载CUDA的安装程序和cudnn的压缩包&#xff0c;然后再…

基于python深度学习遥感影像地物分类与目标识别、分割

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB&#xff0c;遥感大数据时…

海康 Java SDK 升级 JNA 版本

海康 Java SDK 依赖 JNA 3.0.9&#xff0c;业务中已经使用了更高版本的 JNA&#xff0c;所以需要升级&#xff0c;记录一下从 JNA 3.0.9 升级 JNA 5.15.0 的方法。 海康 Java SDK 核心类是 HCNetSDK&#xff0c;JNA 升级需要处理继承自 com.sun.jna.Structure 类&#xff0c;覆…

WebSocket(WS)协议系列(一)基本概念

ws协议是什么&#xff1f; WebSocket&#xff08;WS&#xff09;协议是一种网络通信协议&#xff0c;提供了全双工、单连接、低延迟的通信方式&#xff0c;通常用于浏览器和服务器之间的实时数据交换。与传统的HTTP协议相比&#xff0c;WebSocket允许在客户端和服务器之间建立…

越权漏洞及其修复方法

越权漏洞及其修复方法 1. 越权漏洞的定义 **越权漏洞&#xff08;Authorization Bypass Vulnerability&#xff09;**是指攻击者通过某种方式绕过权限控制&#xff0c;访问或操作其无权访问的资源或功能。这种漏洞通常发生在身份验证和权限管理机制不完善的情况下。 越权漏洞…

自由学习记录(36)

Linux Linux 是一个开源的操作系统&#xff0c;其内核及大部分组件都遵循自由软件许可证&#xff08;如 GPL&#xff09;&#xff0c;允许用户查看、修改和分发代码。这种开放性使得开发者和企业可以根据自己的需求定制系统​。 “Linux”严格来说只是指由Linus Torvalds最初开…

Linux的基础指令和环境部署,项目部署实战(下)

目录 上一篇&#xff1a;Linxu的基础指令和环境部署&#xff0c;项目部署实战&#xff08;上&#xff09;-CSDN博客 1. 搭建Java部署环境 1.1 apt apt常用命令 列出所有的软件包 更新软件包数据库 安装软件包 移除软件包 1.2 JDK 1.2.1. 更新 1.2.2. 安装openjdk&am…

内核数据结构用法(2)list

list 在 Linux 内核中&#xff0c;链表操作是通过一组宏和函数来实现的&#xff0c;这些操作通常用来管理和遍历链表。以下是一些常用的链表函数和宏的具体用法。 1. 定义链表节点 首先&#xff0c;你需要定义一个包含 struct list_head 的结构体&#xff1a; #include <…