最近在工作项目中,遇到一个需求:
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();
}
到此,已经处理完毕,编译运行即可!