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

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

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();
}

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

<think>好的,我现在要解决用户的问题:如何在QtQLabel中实现图片自适应大小的功能。根据用户提供的引用内容,我需要先理解现有的方法,并整理出一个清晰的步骤。 首先,用户提到了三个引用。引用[1]展示了使用setPixmap来设置缩放后的图片,但可能没有提到自动调整。引用[2]指出在QLabel的构造函数中设置setScaledContents(true),这样可以让图片自适应label的大小。同时,用户还提到不要使用布局管理器,因为可能导致无法缩小的问题。引用[3]则提到了槽函数处理图片,可能需要结合调整QLabel的尺寸。 我需要将这些信息整合起来。首先,设置setScaledContents(true)是关键,这会让图片根据QLabel大小进行缩放。但用户可能还需要确保QLabel本身的尺寸能够随着窗口变化而调整,这时候可能需要通过布局管理或者手动调整QLabel大小。 另外,用户提到不使用布局管理器,但可能在实际应用中,如果父窗口使用了布局,QLabel的尺寸管理可能需要调整。例如,将QLabel放在一个布局中,并设置其尺寸策略,或者重写resizeEvent来动态调整图片大小。 还有,当加载不同比例的图片时,可能需要保持宽高比。虽然setScaledContents(true)会拉伸图片填满,但可能造成变形。因此,可能需要在缩放时保持比例,比如在槽函数中计算合适的尺寸,并调整QPixmap的大小,然后再设置QLabel上。 总结步骤可能包括:设置setScaledContents(true),调整QLabel的尺寸策略,处理窗口大小变化事件,或者在加载图片时动态调整图片尺寸以保持比例。需要注意避免使用布局管理器可能导致的问题,或者在必要时正确使用布局。</think>在Qt中实现QLabel图片自适应大小功能,可以通过以下步骤实现: ### 一、基础设置方法 1. **启用缩放属性** 在QLabel对象上调用`setScaledContents(true)`,这是核心设置项: ```cpp ui->label->setScaledContents(true); // 自动拉伸图片填充整个label区域[^2] ``` 2. **加载图片时的处理** 使用`QPixmap::scaled()`方法实现等比缩放: ```cpp QPixmap pix("image.jpg"); pix = pix.scaled(ui->label->size(), Qt::KeepAspectRatio); // 保持宽高比 ui->label->setPixmap(pix); ``` ### 二、动态自适应实现 1. **重写窗口大小事件** 在父窗口的resizeEvent中更新图片: ```cpp void Widget::resizeEvent(QResizeEvent* event) { QPixmap pix("image.jpg"); pix = pix.scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); ui->label->setPixmap(pix); } ``` 2. **结合布局管理器** 虽然引用[2]提示不要使用布局管理器,但可通过以下方式安全使用: ```cpp QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(ui->label); ui->label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // 禁用自动尺寸计算 ``` ### 三、进阶技巧 1. **保持宽高比的自适应** 使用比例计算避免变形: ```cpp QPixmap scaledPix = originalPix.scaled( labelWidth, labelHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation ); ``` 2. **全屏显示优化** 对于全屏需求,可以绑定屏幕分辨率: ```cpp QScreen *screen = QGuiApplication::primaryScreen(); QRect screenGeometry = screen->geometry(); pix = pix.scaled(screenGeometry.width(), screenGeometry.height(), Qt::KeepAspectRatio); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值