【从零开始的Qt开发指南】(八)Qt 常用控件之显示类控件(上):Label 与 LCD Number 实战指南


目录

前言

[一、Label 控件:Qt 的 "万能显示面板"](#一、Label 控件:Qt 的 "万能显示面板")

[1.1 Label 核心属性解析](#1.1 Label 核心属性解析)

[1.2 文本显示:从纯文本到 Markdown 的全支持](#1.2 文本显示:从纯文本到 Markdown 的全支持)

[1.3 图片显示:从本地图片到资源文件的完美适配](#1.3 图片显示:从本地图片到资源文件的完美适配)

[1.4 文本排版高级技巧:对齐、换行、缩进与边距](#1.4 文本排版高级技巧:对齐、换行、缩进与边距)

[1.5 实用进阶功能:Buddy 关联](#1.5 实用进阶功能:Buddy 关联)

[1.6 Label 常见问题与避坑指南](#1.6 Label 常见问题与避坑指南)

[问题 1:图片加载失败](#问题 1:图片加载失败)

[问题 2:文本不自动换行](#问题 2:文本不自动换行)

[问题 3:富文本 / Markdown 格式不生效](#问题 3:富文本 / Markdown 格式不生效)

[问题 4:图片拉伸后变形](#问题 4:图片拉伸后变形)

[二、LCD Number 控件:复古风格的数字显示神器](#二、LCD Number 控件:复古风格的数字显示神器)

[2.1 LCD Number 核心属性解析](#2.1 LCD Number 核心属性解析)

[2.2 基础用法:固定数值与格式切换](#2.2 基础用法:固定数值与格式切换)

[2.2.1 固定数值显示](#2.2.1 固定数值显示)

[2.2.2 进制切换功能](#2.2.2 进制切换功能)

[2.3 实战案例 :秒表倒计时功能](#2.3 实战案例 :秒表倒计时功能)

关键技术点解析:

[2.4 LCD Number 使用注意事项](#2.4 LCD Number 使用注意事项)

总结


前言

在 Qt GUI 开发中,显示类控件是构建界面的 "视觉基石"------ 它们负责呈现文本、图片、数字等核心信息,直接影响用户对程序的第一印象。Label 作为最灵活的显示控件,既能展示简单文字,又能承载图片渲染;LCD Number 则以复古计算器风格的数字显示,成为数据可视化的特色选择。本文将结合 Qt 5.14 实战案例,从基础属性到高级技巧,全面拆解这两个控件的用法,带你轻松掌握显示类控件的核心技能!下面就让我们正式开始吧!


一、Label 控件:Qt 的 "万能显示面板"

QLabel 是 Qt 中最常用的显示控件,没有之一。它就像一块可编程的电子黑板,既能用朴素的文字传递信息,也能展示高清图片,甚至支持富文本和 Markdown 格式渲染。无论是简单的状态提示,还是复杂的图文组合,Label 都能轻松胜任。

1.1 Label 核心属性解析

Label 的强大之处在于其丰富的可配置属性,通过 Qt Designer 或代码均可灵活调整,以下是最常用的核心属性:

属性名 功能说明 实用场景
text 设置显示文本内容 状态提示、标题展示
textFormat 指定文本格式(纯文本 / 富文本 / Markdown) 富文本文档展示、Markdown 笔记
pixmap 关联图片资源 图标显示、产品展示图
scaledContents 图片自动拉伸填充 自适应窗口大小的背景图
alignment 文本 / 图片对齐方式 居中展示、左对齐排版
wordWrap 文本自动换行 长文本说明展示
indent 文本缩进 段落排版、正文格式优化
margin 内边距(上下左右统一设置) 控件内部留白,提升美观度
openExternalLinks 允许打开外部链接 带跳转功能的文本提示
buddy 关联其他控件(点击 Label 激活关联控件) 表单标签与输入框联动

这些属性并非孤立存在,合理组合能实现多样化的显示效果。例如,结合**scaledContentsalignment可实现图片居中并自适应控件大小;搭配wordWrapindent**能让长文本呈现专业的排版效果。

1.2 文本显示:从纯文本到 Markdown 的全支持

Label 对文本的支持覆盖了从简单到复杂的全场景,不同**textFormat**对应不同的使用场景,下面通过实战案例为大家演示一下。

我们先通过.ui文件创建几个label控件:

在widget.cpp文件中编写如下代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //把第一个label设置成显示纯文本
    ui->label->setTextFormat(Qt::PlainText);
    ui->label->setText("这是一段纯文本");

    //把第二个label设置成显示富文本
    ui->label_2->setTextFormat(Qt::RichText);
    ui->label_2->setText("<b>这是一段富文本"); //<b>:让文本加粗

    //把第一个label设置成显示markdown
    ui->label_3->setTextFormat(Qt::MarkdownText);
    ui->label_3->setText("# 这是一段markdown文本");   //#:一级标题
}

Widget::~Widget()
{
    delete ui;
}

运行结果如下:

通过上述案例我们可以知道,纯文本是最基础的使用场景,适用于简单的文字提示;富文本支持 HTML 标签,可实现字体样式、颜色、链接等复杂效果;Qt 5.14 及以上版本支持 Markdown 格式,它无需手动编写 HTML 标签,就能实现结构化排版杂效果,常用于需要排版优化的文本展示。

1.3 图片显示:从本地图片到资源文件的完美适配

Label 不仅能显示文本,还是图片展示的常用控件。Qt 支持多种图片格式(JPG、PNG、GIF 等),图片加载方式分为本地路径加载和资源文件加载两种,其中资源文件加载是项目开发的首选方式。下面我们将通过资源文件加载来加载图片。

Qt 的资源文件(.qrc)能将图片、字体等资源嵌入可执行文件,避免路径依赖问题,步骤如下:

  1. 创建资源文件 :在 Qt Creator 中右键项目 → Add New → Qt → Qt Resource File,命名为resource.qrc
  2. 添加图片资源 :在资源编辑器中点击 "Add Prefix",设置前缀为/,然后点击 "Add Files" 添加图片文件。
  3. 代码中引用资源 :使用:/前缀/文件名的格式引用图片。

由于上述步骤已经在之前的博客中为大家详细展示过了,这里就不多赘述,直接编写代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QResizeEvent>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //先把QLabel设置成和窗口一样大,并且把QLabel左上角设置到窗口的左上角
    //让整个QLabel铺满整个窗口
    QRect windowRect = this->geometry();
    ui->label->setGeometry(0, 0, windowRect.width(), windowRect.height());

   QPixmap pixmap(":/anno.png");
   ui->label->setPixmap(pixmap);

   //启动自动拉伸,图片就可以填充满整个窗口了
   ui->label->setScaledContents(true);
}

Widget::~Widget()
{
    delete ui;
}

//此处的形参event是非常有用的,这里就包含了触发这个resize时间这一时刻,窗口的尺寸的数值
void Widget::resizeEvent(QResizeEvent *event)
{
    qDebug() << event->size();
    ui->label->setGeometry(0, 0, event->size().width(), event->size().height());
}

由于在实际开发中常需要图片随窗口大小变化而自适应,因此在上述代码中我们还需要重写resizeEvent函数,在窗口大小改变时同步调整 Label 尺寸。

运行程序后,拖动窗口边缘改变大小,图片会自动拉伸填充整个窗口,且保持比例不变(scaledContents属性会自动处理比例适配)。

1.4 文本排版高级技巧:对齐、换行、缩进与边距

良好的排版能提升界面的专业度,Label 提供的alignment、wordWrap、indent、margin等属性,可实现媲美专业文档的排版效果。

我们先来创建四个label控件,来分别展示着四个效果:

编写代码如下:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //在构造函数中,给这几个label设置不同的属性

    //设置对齐方式
    ui->label->setText("这是一段文本");
    ui->label->setAlignment(Qt::AlignRight | Qt::AlignTop);  //水平靠右对齐+垂直靠上对齐

    //设置自动换行
    ui->label_2->setText("这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 v 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本 这是一段很长的文本 这是一段很长的文本这是一段很长的文本");
    ui->label_2->setWordWrap(true);  //开启自动换行

    //设置缩进
    ui->label_3->setText("这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 v 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本 这是一段很长的文本 这是一段很长的文本这是一段很长的文本");
    ui->label_3->setWordWrap(true);
    ui->label_3->setIndent(50);

    //设置边距
    ui->label_4->setText("这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 v 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本 这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本这是一段很长的文本 这是一段很长的文本 这是一段很长的文本这是一段很长的文本");
    ui->label_4->setWordWrap(true);
    ui->label_4->setMargin(50);
}

Widget::~Widget()
{
    delete ui;
}

运行结果如下:

1.5 实用进阶功能:Buddy 关联

Label 的进阶功能能提升用户交互体验,其中 Buddy 关联是最常用的场景。

在表单界面中,常常需要点击标签激活对应的输入框,这可以通过setBuddy方法实现:

先通过.ui文件创建label控件和Radio Button:

编写代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置label和radioButton的伙伴关系
    ui->label->setBuddy(ui->radioButton);
    ui->label_2->setBuddy(ui->radioButton_2);
}

Widget::~Widget()
{
    delete ui;
}

运行结果如下:

运行程序后,按下"ALT + A"就会自动选择选项一,按下"ALT + B"就会自动选择选项二,通过绑定伙伴关系,能够极大提升表单操作的便捷性。

1.6 Label 常见问题与避坑指南

在使用 Label 的过程中,难免会遇到一些问题,这里总结了几个高频问题及解决方案:

问题 1:图片加载失败

  • 原因 1:路径错误(绝对路径拼写错误、相对路径基准目录不正确)
  • 原因 2:资源文件未正确添加(未添加到.qrc 文件,或前缀与代码中引用不一致)
  • 解决方案:
    1. 测试阶段使用绝对路径快速验证图片是否可用
    2. 项目开发时务必使用资源文件,确保前缀和文件名与代码一致
    3. 检查图片格式是否支持(Qt 支持 JPG、PNG、GIF 等常见格式,不支持 WebP 等特殊格式)

问题 2:文本不自动换行

  • 原因:未启用wordWrap属性,或控件宽度设置过大
  • 解决方案:
    1. 调用setWordWrap(true)启用自动换行
    2. 确保控件宽度小于文本长度(可通过setGeometry固定宽度,或使用布局管理器自动调整)

问题 3:富文本 / Markdown 格式不生效

  • 原因:未设置textFormat属性,默认使用纯文本格式
  • 解决方案:
    1. 富文本设置:setFormat(Qt::RichText)
    2. Markdown 设置:setFormat(Qt::MarkdownText)
    3. 注意:Markdown 支持仅在 Qt 5.14 及以上版本可用

问题 4:图片拉伸后变形

  • 原因:scaledContents属性会强制图片填充控件,可能导致比例失调
  • 解决方案:
    1. 手动缩放图片并保持比例:

      cpp 复制代码
      QPixmap pixmap(":/images/test.png");
      // 按比例缩放图片,宽度为200,高度自动计算
      QPixmap scaledPixmap = pixmap.scaled(200, pixmap.height() * 200 / pixmap.width(), Qt::KeepAspectRatio);
      label->setPixmap(scaledPixmap);
    2. 使用Qt::KeepAspectRatio参数保持图片比例

二、LCD Number 控件:复古风格的数字显示神器

QLCDNumber 是 Qt 专门用于数字显示的控件,以老式计算器的 LCD 屏幕为设计风格,支持十进制、十六进制、八进制、二进制等多种数字格式,常用于计数器、定时器、数据监控等场景。其独特的显示风格能为界面增添别样的设计感。

2.1 LCD Number 核心属性解析

LCD Number 的属性围绕数字显示展开,核心属性如下:

属性名 功能说明 取值 / 类型 实用场景
intValue 显示的整数数值 int 整数计数器、整数数据展示
value 显示的浮点数数值 double 带小数的数值展示(如温度、湿度)
digitCount 显示的数字位数 int 固定位数的数字展示(如时间、编号)
mode 数字显示模式 Dec(十进制)/Hex(十六进制)/Bin(二进制)/Oct(八进制) 不同进制的数字展示
segmentStyle 显示风格 Flat(平面)/Outline(轮廓)/Filled(填充) 界面风格适配
smallDecimalPoint 显示小型小数点 bool 节省空间的小数显示

其中,intValuevalue****是联动的 ,修改其中一个会同步更新另一个(例如,value设为 1.5 时,intValue会自动取整为 2);digitCount设置后,数字会自动补零以满足位数要求(如digitCount设为 5,数值为 123 时,会显示 00123)。

2.2 基础用法:固定数值与格式切换

LCD Number 的基础用法非常简单,只需设置核心属性即可实现数字显示,下面通过案例演示固定数值显示和进制切换功能。

2.2.1 固定数值显示

cpp 复制代码
#include "widget.h"
#include <QLCDNumber>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    // 创建LCD Number控件
    QLCDNumber *fixedLcd = new QLCDNumber(this);
    fixedLcd->setGeometry(50, 50, 200, 80);
    // 设置显示位数为6位
    fixedLcd->setDigitCount(6);
    // 设置显示数值(整数)
    fixedLcd->display(12345);
    // 设置显示风格为填充模式
    fixedLcd->setSegmentStyle(QLCDNumber::Filled);
}

2.2.2 进制切换功能

LCD Number 支持四种进制模式,通过setMode方法可随时切换,代码示例如下:

cpp 复制代码
#include "widget.h"
#include <QLCDNumber>
#include <QPushButton>
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    // 创建布局管理器
    QVBoxLayout *layout = new QVBoxLayout(this);
    
    // 创建LCD Number
    lcd = new QLCDNumber(this);
    lcd->setDigitCount(8);
    lcd->display(255); // 初始显示十进制255
    lcd->setSegmentStyle(QLCDNumber::Outline);
    layout->addWidget(lcd);
    
    // 创建进制切换按钮
    QPushButton *decBtn = new QPushButton("十进制", this);
    QPushButton *hexBtn = new QPushButton("十六进制", this);
    QPushButton *binBtn = new QPushButton("二进制", this);
    QPushButton *octBtn = new QPushButton("八进制", this);
    
    // 添加按钮到布局
    layout->addWidget(decBtn);
    layout->addWidget(hexBtn);
    layout->addWidget(binBtn);
    layout->addWidget(octBtn);
    
    // 连接按钮点击信号与槽函数
    connect(decBtn, &QPushButton::clicked, this, [=]() {
        lcd->setMode(QLCDNumber::Dec);
        lcd->display(255);
    });
    
    connect(hexBtn, &QPushButton::clicked, this, [=]() {
        lcd->setMode(QLCDNumber::Hex);
        lcd->display(255); // 十六进制显示FF
    });
    
    connect(binBtn, &QPushButton::clicked, this, [=]() {
        lcd->setMode(QLCDNumber::Bin);
        lcd->display(255); // 二进制显示11111111
    });
    
    connect(octBtn, &QPushButton::clicked, this, [=]() {
        lcd->setMode(QLCDNumber::Oct);
        lcd->display(255); // 八进制显示377
    });
}

运行程序后,点击不同的按钮,LCD Number 会切换对应的进制显示 255,直观展示四种进制的转换效果。需要注意的是,只有十进制模式支持显示小数,其他进制模式仅支持整数显示。

2.3 实战案例 :秒表倒计时功能

LCD Number 最经典的应用场景之一是倒计时 / 计时器,结合 Qt 的 QTimer 控件,可实现精准的时间控制。下面实现一个 10 秒倒计时功能:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //先设置一个初始值
    ui->lcdNumber->display("10");

    //创建一个QTimer实例
    QTimer* timer = new QTimer(this);
    //把QTimer的timeout信号和咱们自己的槽函数进行连接
    connect(timer, &QTimer::timeout, this, &Widget::handle);
    //启动定时器(参数是触发timeout的周期,单位是ms)
    timer->start(1000);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
    //先拿到LCDNumber中的数字
    int value = ui->lcdNumber->intValue();
    if(value <= 0)
    {
        //数字减到0了,停止计时器
        timer->stop();
        return;
    }
    ui->lcdNumber->display(value - 1);
}
关键技术点解析:
  1. QTimer 定时器 :通过**timer->start(1000);**设置定时周期(1000 毫秒 = 1 秒),start方法启动定时器,timeout信号触发倒计时更新。
  2. 数值更新逻辑:每次定时器触发时,获取当前 LCD 数值,减 1 后重新显示,直到数值为 0 时停止定时器。
  3. 资源释放:在析构函数中释放定时器资源,避免内存泄漏。

2.4 LCD Number 使用注意事项

  1. 小数显示限制:只有十进制模式(Dec)支持小数显示,其他进制模式仅支持整数。
  2. 位数设置digitCount应根据显示数值的最大位数设置,若数值位数超过digitCount,会显示为 "--------"(溢出提示)。
  3. 显示风格适配segmentStyle的选择应与整体界面风格一致,Flat(平面)风格简洁现代,Outline(轮廓)和 Filled(填充)风格更具复古感。
  4. 非数字显示:LCD Number 除了显示数字,还支持显示部分字符(如 "0-9"、"A-F"、"-"、""、"E"、"N"、"D"),可用于显示简单的状态提示(如倒计时结束显示"END")。
  5. 性能优化:在实时数据监控场景中,定时器周期不宜过短(建议不小于 100 毫秒),避免频繁更新导致界面卡顿。

总结

显示类控件是 Qt 界面开发的基础,掌握 Label 和 LCD Number 的使用后,可进一步学习 ProgressBar(进度条)、CalendarWidget(日历)等其他显示类控件,构建更丰富、更专业的 Qt 界面。

后续将推出《Qt 常用控件之显示类控件(下)》,详细讲解 ProgressBar、CalendarWidget 等控件的使用,敬请期待!如果本文对你有帮助,欢迎点赞、收藏、转发,如有疑问或建议,欢迎在评论区留言交流~

相关推荐
码农水水2 分钟前
京东Java面试被问:系统限流的实现方式
java·开发语言·面试
CodeOfCC6 分钟前
C++ 基于kmp解析nalu
c++·音视频·实时音视频·h.265·h.264
Sheep Shaun7 分钟前
STL中的map和set:红黑树的优雅应用
开发语言·数据结构·c++·后端·c#
宁大小白9 分钟前
pythonstudy Day45
开发语言·python·深度学习
Yu_iChan22 分钟前
Day03 公共字段填充与菜品管理
java·开发语言
独自破碎E24 分钟前
如何防止接口被恶意刷量?
java·开发语言
期待のcode36 分钟前
Java的单例模式
java·开发语言·单例模式
Aliex_git44 分钟前
内存堆栈分析笔记
开发语言·javascript·笔记
LYOBOYI1231 小时前
qml练习:创建地图玩家并且实现人物移动(2)
开发语言·qt
电商API&Tina1 小时前
【电商API接口】多电商平台数据API接入方案(附带实例)
运维·开发语言·数据库·chrome·爬虫·python·jenkins