【Qt入门系列】:QLabel控件详解:从文本显示到图片展示,再到内容布局与伙伴机制

🔥 本文专栏:Qt

🌸作者主页:努力努力再努力wz

💪 今日博客励志语录今天,是你最年轻的一天。别等"准备好"------准备好这件事永远不会发生,你只会在做的过程中慢慢变好。


思维导图

引入

在此前的学习中,我们已经接触了 Qt 中一类常见的控件:按钮类。

需要注意的是,Qt 中的按钮并不是由某一个单独的类来描述的,而是由一组按钮相关的类共同构成。例如,QPushButton 表示普通按钮,QRadioButton 表示单选按钮,QCheckBox 表示复选按钮。虽然这些按钮在具体的外观和使用场景上有所不同,但是它们都具备一些共同的属性和行为。

因此,Qt 将按钮类共有的能力抽象到了 QAbstractButton 类中。例如,按钮的文本、图标、选中状态,以及 clickedpressedreleasedtoggled 等信号,都属于按钮类较为通用的特征。

同时,QAbstractButton 本身是一个抽象类,由于其中包含纯虚函数,因此该类不能被直接实例化,也就不能用来创建具体的按钮对象。它主要作为按钮类的公共父类存在,用来抽象按钮类共有的属性和行为。具体的按钮类,例如 QPushButtonQRadioButtonQCheckBox,会在继承 QAbstractButton 的基础上,实现各自不同的外观表现和行为细节。

从继承关系上看,QAbstractButton 又继承自 QWidget。而 QWidget 是 Qt 图形界面控件体系中的重要基类,它为控件提供了可视化显示能力,例如控件的位置、大小、显示区域、事件处理等基础能力。因此,按钮类通过间接继承 QWidget,也就具备了在图形化界面中显示出来的能力。

不过,对于按钮类来说,它的核心并不只是"显示一个控件",而是作为用户操作的入口。用户点击按钮、切换按钮状态、触发快捷键时,按钮对象会通过信号机制将这些操作通知给程序,从而完成交互逻辑的处理。它的核心并不在于静态地展示自己,而在于动态交互

而本文要介绍的,正是这样一个偏向静态展示的控件------QLabel 类。

QLabel 控件详解

QLabel 文本显示:普通文本、富文本与样式控制

对于 QLabel 类来说,根据前文的分析可以知道,它是一个更偏向于内容展示的控件。和按钮类相比,QLabel 的核心职责并不是接收用户点击,也不是作为交互入口,而是在界面中的某个区域显示一段内容。

最常见的情况下,QLabel 用来显示一段文本。例如,我们可以在 Qt Designer 的可视化编辑界面中,直接设置标签控件要显示的文本;也可以在代码中,通过调用 QLabel 提供的 setText() 接口来设置文本内容:

cpp 复制代码
ui->label->setText("hello Qt");

这里需要注意的是,setText() 设置的是 QLabel 中保存的字符串内容。至于这段字符串最终是按照普通文本原样显示,还是按照富文本解析成特殊的显示效果,则取决于 QLabel 的 textFormat 属性。

例如,下面这段代码设置的字符串内容是相同的:

cpp 复制代码
ui->label->setText("<b>这是一段文字</b>");

如果 QLabel 按照普通文本来解析,那么界面上会原样显示:

cpp 复制代码
<b>加粗</b>

如果 QLabel 按照富文本来解析,那么 <b></b> 不会作为普通字符显示出来,而是会被解释成富文本标记,最终界面上只显示"加粗"两个字,并且这两个字会呈现加粗效果。

因此,富文本并不是单纯的普通字符串,而是在字符串中嵌入了一些 HTML 风格的标记。QLabel 在显示这类字符串时,会先根据这些标记解析文本内容,然后在绘制时渲染成对应的显示效果。

例如:

cpp 复制代码
ui->label->setText("<b>加粗</b>");
ui->label->setText("<i>斜体</i>");
ui->label->setText("<u>下划线</u>");
ui->label->setText("<s>删除线</s>");
ui->label->setText("<br>换行");
ui->label->setText("<font color='red'>红色文字</font>");
ui->label->setText("<h1>一级标题</h1>");
ui->label->setText("<p align='center'>居中文本</p>");
ui->label->setText("<img src=':/image/test.png'>");

不过需要注意,连续多次调用 setText() 时,后一次设置的内容会覆盖前一次设置的内容。因此,上面的代码主要用于分别展示不同富文本标记的写法。如果希望在同一个 QLabel 中同时显示多个效果,可以将它们写在同一个字符串中:

cpp 复制代码
ui->label->setText(
    "<b>加粗</b><br>"
    "<i>斜体</i><br>"
    "<u>下划线</u><br>"
    "<font color='red'>红色文字</font>"
);

为了明确告诉 QLabel 应该如何解析这段字符串,我们可以调用 setTextFormat() 接口来设置文本格式:

cpp 复制代码
ui->label->setTextFormat(Qt::PlainText);
ui->label->setText("<b>加粗</b>");

当文本格式设置为 Qt::PlainText 时,QLabel 会把字符串当成普通文本处理,也就是原样显示 <b>加粗</b>

而如果设置为富文本格式:

cpp 复制代码
ui->label->setTextFormat(Qt::RichText);
ui->label->setText("<b>加粗</b>");

那么 QLabel 会把字符串当成富文本处理,识别其中的 HTML 风格标记,并将其渲染成对应的显示效果。

除了 Qt::PlainTextQt::RichText 之外,QLabel 默认使用的是 Qt::AutoText。也就是说,如果我们没有手动指定文本格式,QLabel 会尝试根据字符串内容自动判断它应该按照普通文本解析,还是按照富文本解析。

在使用 QLabel 显示文本时,还需要区分 styleSheet 和富文本格式之间的关系。

首先,styleSheet 用来描述控件整体的外观样式。对于 QLabel 来说,它不仅可以设置控件的背景色、边框等外观属性,也可以影响文本的显示效果,例如文字颜色、字体大小、字体粗细等。其设置方式是调用 setStyleSheet() 接口,并传入一段类似 CSS 的样式规则字符串:

cpp 复制代码
ui->label->setStyleSheet("color: red; font-size: 20px; font-weight: bold;");

这段代码表示让 QLabel 中显示的文本整体变为红色,并设置字体大小和加粗效果。也就是说,styleSheet 更偏向于从控件整体的角度描述外观,它控制的是这个 QLabel 在界面中应该如何显示。

而富文本格式则不同。富文本并不是通过单独的样式接口来描述文本外观,而是将格式标记直接嵌入到 setText() 设置的字符串内容中。例如:

cpp 复制代码
ui->label->setText("普通文字 <b>加粗文字</b> <i>斜体文字</i>");

在这段字符串中,<b><i> 等标记本身并不是最终要显示出来的普通文本,而是用于描述局部文本格式的富文本标记。当 QLabel 按照富文本方式解析这段字符串时,这些标记会被解释成对应的显示效果,从而让其中某一部分文字加粗,另一部分文字变成斜体。

因此,styleSheet 和富文本格式虽然都可以影响文本的显示效果,但它们的侧重点并不相同。styleSheet 更适合控制 QLabel 这个控件整体的显示样式,例如让整段文字统一变色、统一加粗、统一改变字号;而富文本更适合控制字符串内部的局部格式,例如让某一段文字正常显示,某一段文字加粗,某一段文字变成斜体。

简单来说,styleSheet 是控件级样式,而富文本是内容级样式。前者描述的是整个控件如何显示,后者描述的是文本内容内部的不同部分如何显示。

因此,可以将三者的职责区分开来:

setText() 负责设置 QLabel 要显示的字符串内容;

setTextFormat() 负责决定 QLabel 如何解析这段字符串;

styleSheet 负责控制 QLabel 这个控件整体的外观样式。

也就是说,QLabel 显示文本时,并不是简单地把字符串直接绘制到界面上,而是会先根据文本格式判断这段字符串的解析方式。如果是普通文本,就原样显示;如果是富文本,就解析其中的 HTML 风格标记,并在绘制时呈现出加粗、斜体、颜色、标题、图片等不同的显示效果。

QLabel 图片显示:资源系统、QPixmap 与自适应缩放

根据前面的学习,我们已经认识了 QLabel 如何显示普通文本以及富文本。实际上,QLabel 并不只能显示文字,它同样可以在自身区域中显示图片。

如果希望在 QLabel 中显示一张图片,首先需要准备一个图片资源文件,例如 pngjpg 格式的图片。为了方便程序访问这些资源,Qt 提供了资源系统。我们可以将图片添加到 .qrc 资源文件中。

.qrc 文件本质上是一个 XML 格式的资源描述文件,它会描述资源文件的虚拟前缀以及资源文件在项目中的实际路径。程序在访问资源时,并不是直接使用图片在磁盘中的真实路径,而是通过 :/ 开头的虚拟资源路径来访问。

在构建项目时,Qt 的 rcc 工具会读取 .qrc 文件,并根据其中描述的资源信息生成对应的资源代码。资源文件的二进制数据以及相关的索引信息会被编译进最终程序中。这样,程序运行时就可以根据虚拟资源路径,在资源系统中找到对应的资源数据。

例如,假设我们已经将图片添加到了资源系统中,那么可以通过如下方式构造一个 QPixmap 对象:

cpp 复制代码
QPixmap pixmap(":/image/test.png");

这里的 :/image/test.png 并不是普通的磁盘路径,而是 Qt 资源系统提供的虚拟资源路径。当 QPixmap 加载该路径时,会根据传入的虚拟资源路径,交给 Qt 资源系统进行查找。Qt 资源系统会根据编译进程序中的资源索引信息,定位到该路径对应的图片资源数据,也就是图片文件原本的二进制字节流。

随后,QPixmap 会根据图片格式对这些字节数据进行解析和解码。例如,对于 pngjpg 格式的图片,QPixmap 会将其解码成可以用于图形显示的像素数据,并存储到 QPixmap 对象内部。这样,后续我们再将该 QPixmap 对象设置给 QLabel 时,QLabel 就可以直接使用这个已经加载完成的图像对象进行显示。

接下来,如果希望让 QLabel 显示这张图片,就可以调用 setPixmap() 接口:

cpp 复制代码
ui->label->setPixmap(pixmap);

因此,QLabel 显示图片的基本流程可以理解为:

cpp 复制代码
图片文件
    ↓
添加到 .qrc 资源文件
    ↓
rcc 工具生成资源代码
    ↓
程序运行时通过 :/ 虚拟路径访问资源
    ↓
Qt 资源系统根据索引信息定位图片字节流
    ↓
QPixmap 解码图片数据并保存为可显示的图像对象
    ↓
QLabel::setPixmap() 显示图片

这里需要注意三个对象之间的职责边界:Qt 资源系统负责将图片资源嵌入程序,并提供 :/ 虚拟路径进行访问;QPixmap 负责根据资源路径加载图片,并将图片数据解码成可以用于显示的图像对象;而 QLabel 则负责在自己的控件区域中显示这个 QPixmap

在显示图片时,我们还可以调用 setScaledContents() 接口:

cpp 复制代码
ui->label->setScaledContents(true);

该接口的作用是让 QLabel 在显示图片时,将图片按照 QLabel 当前的可用区域进行缩放,使图片能够填满 QLabel 的显示区域。需要注意的是,setScaledContents(true) 只负责让图片填满 QLabel 当前的区域,并不会自动改变 QLabel 本身的大小。

例如,如果我们在 Widget 构造函数中写下如下代码:

cpp 复制代码
QPixmap pixmap(":/image/test.png");

ui->label->setPixmap(pixmap);
ui->label->setScaledContents(true);
ui->label->resize(this->size());

那么在程序刚启动时,QLabel 的大小会被设置为当前窗口的大小。由于此时已经开启了 setScaledContents(true),所以图片会按照 QLabel 的当前大小进行缩放,并填满整个 QLabel 区域。

但是,当程序运行起来之后,如果用户拖动窗口边缘改变窗口大小,就会发现图片并不会自动跟随窗口一起变化。这是因为上面的代码只在构造函数中执行了一次,它只设置了 QLabel 的初始大小。后续窗口大小发生变化时,QLabel 的大小并不会因为构造函数中的这段代码而自动重新调整。

也就是说,这里的问题并不是 QPixmap 没有缩放能力,而是 QLabel 本身的大小没有跟随窗口变化。setScaledContents(true) 只能让图片填满 QLabel 当前的显示区域;如果 QLabel 自己的大小没有变化,那么图片也只能继续填满原来的 QLabel 区域,而无法铺满变化后的窗口。

当用户拖动窗口改变大小时,窗口系统会感知到窗口尺寸变化,并将对应的 resize 事件传递给 Qt 程序。Qt 接收到该事件后,会将其封装为 Qt 自己的事件对象,并分发给对应的窗口对象。事件进入 Widget 对象后,会先进入 event() 函数,再根据事件类型调用对应的事件处理函数,也就是 resizeEvent()

需要注意的是,resizeEvent() 并不是用来修改窗口自身大小的。因为当该事件被触发时,窗口的新大小已经确定了。QWidgetresizeEvent()基类默认实现基本什么都不做,即它不会去调整子控件的大小和位置。它本质上只是 Qt 提供的一个事件处理入口,用来通知当前这个 QWidget:你的尺寸已经发生变化了。

因此,如果我们希望窗口缩放之后,内部的 QLabel 也能跟随窗口一起变化,就需要在自定义的 Widget 类中重写 resizeEvent() 虚函数,并在该函数中根据窗口当前的新尺寸,手动调整 QLabel 的大小。

例如:

cpp 复制代码
void Widget::resizeEvent(QResizeEvent *event)
{
    ui->label->resize(this->size());

    QWidget::resizeEvent(event);
}

这样,每当窗口大小发生变化时,resizeEvent() 都会被调用。此时我们在该函数中重新设置 QLabel 的大小,让它始终和当前窗口一样大。由于前面已经调用了:

cpp 复制代码
ui->label->setScaledContents(true);

所以当 QLabel 的大小发生变化后,其中显示的图片也会跟着重新缩放,并继续填满整个 QLabel 区域。这样就可以实现窗口缩放时,图片始终铺满整个窗口的效果。

因此,整个过程可以总结为:

cpp 复制代码
setPixmap() 负责决定 QLabel 显示哪一张图片;

setScaledContents(true) 负责决定图片是否缩放并填满 QLabel 当前区域;

resizeEvent() 负责在窗口大小变化时,手动同步调整 QLabel 这个子控件的大小。

也就是说,setScaledContents(true) 只能让图片填满 QLabel,但不能让 QLabel 自动填满窗口。如果希望图片随着窗口缩放而始终铺满整个窗口,就需要让 QLabel 的大小也跟随窗口变化。而在当前这种手动设置控件大小的写法中,就需要通过重写 resizeEvent() 来完成这个同步过程。

QLabel 文本布局:自动换行、边距缩进与对齐方式

根据前面的学习,我们已经认识了 QLabel 如何处理文本格式以及图片显示。接下来,我们继续关注 QLabel 内部内容的排布方式,也就是标签中的文本在控件区域内如何显示。

首先需要注意的是,QLabel 中的文本默认是不会自动换行的。如果我们通过 setText() 给标签设置了一段很长的字符串,而这段字符串的长度超过了 QLabel 当前的显示区域,那么超出边界的部分就无法继续正常显示,可以理解为被标签的显示区域裁剪掉了。

例如:

cpp 复制代码
ui->label->setText("这是一段非常非常非常非常非常长的字符串");

如果希望长文本能够在超过边界时自动换到下一行显示,就可以调用 setWordWrap() 接口:

cpp 复制代码
ui->label->setWordWrap(true);

当开启自动换行之后,如果当前行剩余空间不足以继续显示后续文本,QLabel 就会根据换行规则,将后续内容显示到下一行中。这样,即使文本内容较长,也可以在标签内部以多行的形式展示出来。

除了自动换行之外,QLabel 还提供了缩进相关的接口,例如 setIndent()

cpp 复制代码
ui->label->setIndent(20);

这里需要注意,setIndent() 并不是用来设置"首行缩进"的。它不是类似 Word 段落中的首行缩进效果,而是用于设置 QLabel 内容相对于当前对齐边缘的缩进距离。

例如,当文本是左对齐时,setIndent(20) 表示文本内容相对于左侧边缘向右缩进 20 个像素;如果文本是右对齐,那么这个缩进效果则会体现在右侧方向上。因此,setIndent() 更准确地说,是根据当前对齐方式,对内容整体施加一个缩进距离。

除了 setIndent() 之外,QLabel 还提供了 setMargin() 接口,用来设置标签内部的边距:

cpp 复制代码
ui->label->setMargin(20);

这里需要注意,setMargin() 设置的并不是文本本身的位置,而是设置 QLabel 内部内容区域与标签边界之间的距离。换句话说,它会让标签内部真正用于显示文本或图片的区域向内收缩。

因此,如果我们给 QLabel 设置了四周边距,并不意味着短字符串左右两侧到标签边界的距离一定相等。因为 setMargin() 只是改变内容区域的位置和大小,而文本在内容区域中如何摆放,还要继续看当前的对齐方式。

例如:

cpp 复制代码
ui->label->setMargin(20);
ui->label->setAlignment(Qt::AlignLeft);
ui->label->setText("hello");

这段代码表示 QLabel 内部用于显示内容的区域会向内收缩 20 像素。此时文本虽然仍然是左对齐,但它对齐的并不是 QLabel 控件最外侧的左边界,而是收缩之后的内容区域的左边界。因此,hello 会靠近内容区域的左侧显示,而不会因为设置了边距就自动居中。

所以,setMargin() 解决的是"内容区域距离标签边界多远"的问题,而 setAlignment() 解决的是"文本在内容区域中如何摆放"的问题。这两个接口的职责并不相同。

这里还可以额外补充一点:QLabel 继承自 QFrame,因此它本身可以具备边框、框架等外观能力。但是,QFrame 并不等于内容区。QFrame 更像是为 QLabel 提供边框显示能力的父类,而内容区则是 QLabel 在显示文本或图片时实际使用的内部区域。

对于一个 QLabel 来说,可以大致理解为:

cpp 复制代码
QLabel 整个控件区域
    ↓
如果存在 frame,则先扣除边框占用的区域
    ↓
再根据 margin 向内收缩一定距离
    ↓
剩下的区域才是文本或图片实际排布的内容区域

因此,setMargin() 并不是直接修改 QFrame 这个父类的属性,而是设置 QLabel 自己的内容边距。它影响的是标签内部内容区域的位置和大小,而不是文本本身的对齐方式。

如果希望文本在标签内部居中显示,就需要设置文本的对齐方式。QLabel 可以通过 setAlignment() 接口设置内容在标签内部的布局方式:

cpp 复制代码
ui->label->setAlignment(Qt::AlignCenter);

setAlignment() 接收的是一个对齐标志。这个标志可以分为水平对齐和垂直对齐两类。

常见的水平对齐方式包括:

cpp 复制代码
Qt::AlignLeft      // 左对齐
Qt::AlignRight     // 右对齐
Qt::AlignHCenter   // 水平居中

常见的垂直对齐方式包括:

cpp 复制代码
Qt::AlignTop       // 顶部对齐
Qt::AlignBottom    // 底部对齐
Qt::AlignVCenter   // 垂直居中

由于这些对齐方式本质上是一些标志位,因此我们可以通过按位或运算,同时设置水平方向和垂直方向的对齐方式:

cpp 复制代码
ui->label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

这表示让文本在水平方向居中,同时在垂直方向也居中。Qt 也提供了一个更简洁的写法:

cpp 复制代码
ui->label->setAlignment(Qt::AlignCenter);

Qt::AlignCenter 可以理解为水平居中和垂直居中的组合。

因此,对于 QLabel 中文本布局相关的接口,可以这样理解:

cpp 复制代码
setWordWrap(true)
    控制文本过长时是否自动换行。

setIndent(int)
    控制内容相对于当前对齐边缘的缩进距离。

setMargin(int)
    控制 QLabel 内部内容区域到标签边界之间的边距。

setAlignment(Qt::Alignment)
    控制内容在 QLabel 内容区域中的水平和垂直对齐方式。

也就是说,QLabel 并不是简单地把文本直接绘制到控件区域中,而是会先根据边框、边距等信息确定内部的内容区域,然后再根据自动换行、缩进和对齐方式,将文本排布到这个内容区域中。

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->label->setText("这是一段非常非常非常非常非常长的字符串");
    ui->label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
     ui->label->setIndent(15);
    ui->label->setMargin(10);
    ui->label->setWordWrap(true);
}

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

QLabel 伙伴机制:通过助记符快速切换输入焦点

文章的最后,我们再来介绍 QLabel 中一个比较特殊的机制:伙伴机制,也就是 buddy 机制。

在前面的学习中,我们已经知道,QLabel 主要用于展示文本或图片。不过在实际的界面设计中,QLabel 经常会和输入类控件一起使用。例如,一个标签显示"用户名",它旁边可能会放置一个 QLineEdit,用于让用户输入用户名。

此时,QLabel 本身虽然不是一个输入控件,但是它可以通过 buddy 机制和另一个控件建立关联。当用户触发标签上的助记符时,Qt 会自动将键盘输入焦点转移到它绑定的伙伴控件上。

QLabel 的文本中,& 具有特殊含义。它并不是普通的显示字符,而是一个助记符标记。Qt 会将 & 后面的字符识别为快捷访问字符。

例如:

cpp 复制代码
ui->label->setText("&Name:");

这里的 &N 表示字母 N 会成为这个标签的助记符。通常情况下,用户可以通过 Alt + N 来触发这个助记符。

如果希望这个助记符真正发挥作用,还需要给 QLabel 设置一个伙伴控件:

cpp 复制代码
ui->label->setText("&Name:");
ui->label->setBuddy(ui->lineEdit);

这段代码表示:labellineEdit 建立伙伴关系。当当前 Qt 窗口处于激活状态时,如果用户按下 Alt + N,Qt 会识别到这个按键组合对应的是 label 上的助记符,于是会将键盘输入焦点转移到 lineEdit 上。

也就是说,QLabel 的助记符并不是为了触发 QLabel 自己的某个业务动作,而是为了帮助用户快速定位到与该标签关联的输入控件。

这一点和之前按钮类中的快捷键机制不同。对于 QPushButton 这类按钮控件来说,快捷键通常用于触发按钮动作。例如用户按下按钮对应的快捷键后,按钮可能会发出 clicked() 信号,从而执行对应的业务逻辑。

但是对于 QLabel 来说,它本身是一个偏向展示的控件,并不负责处理点击后的业务动作。因此,QLabel 中的助记符更多是配合 buddy 机制使用,其核心作用是转移键盘输入焦点。

整个过程可以理解为:

cpp 复制代码
ui->label->setText("&Name:");
        ↓
Qt 将 & 后面的 N 识别为助记符
        ↓
ui->label->setBuddy(ui->lineEdit);
        ↓
QLabel 和 QLineEdit 建立伙伴关系
        ↓
用户按下 Alt + N
        ↓
Qt 识别到该助记符
        ↓
键盘输入焦点转移到 lineEdit

从事件流的角度来看,当用户按下键盘组合键时,底层系统会先接收到键盘输入,然后将该输入分发给当前处于激活状态的窗口。Qt 程序收到键盘输入后,会将其封装成 Qt 内部的事件,并交给 Qt 的事件系统继续处理。

在处理快捷键相关输入时,Qt 会根据当前窗口中的快捷键、助记符等信息,判断这次键盘输入是否对应某个已注册的快捷操作。如果匹配到 QLabel 的助记符,并且该标签已经通过 setBuddy() 绑定了伙伴控件,那么 Qt 就会将输入焦点转移到这个伙伴控件上。

因此,QLabel 的 buddy 机制本质上可以理解为:通过标签文本中的助记符,为用户提供一种快速切换输入焦点的方式。

如果需要显示普通的 & 字符,而不是将其作为助记符使用,则需要写成两个 &

cpp 复制代码
ui->label->setText("Tom && Jerry");

这样界面上最终显示的就是:

cpp 复制代码
Tom & Jerry

所以,QLabel 中的 & 并不是简单的普通字符,而是用于描述助记符的特殊标记。它配合 setBuddy() 使用时,可以让标签和输入控件建立关联,从而通过键盘快捷方式快速切换到对应的输入控件。

从实际应用角度来看,QLabel 的 buddy 机制主要用于表单输入场景。

例如,在一个登录界面中,左侧可能会有一个 QLabel 用来显示"用户名",右侧则是一个 QLineEdit 用来接收用户输入:

cpp 复制代码
ui->label_name->setText("&Name:");
ui->label_name->setBuddy(ui->lineEdit_name);

这里需要注意,& 本身不会作为普通字符显示出来。也就是说,界面上最终显示的文本并不是:

cpp 复制代码
&Name:

而是:

其中 & 后面的字符 N 会被 Qt 识别为助记符。在某些平台或界面样式下,这个字符可能会以下划线的形式显示出来,用来提示用户可以通过快捷键访问该控件。

当用户按下 Alt + N 时,Qt 会识别到这是 label_name 对应的助记符。由于该 QLabel 已经通过 setBuddy() 绑定了 lineEdit_name,所以 Qt 不会让 QLabel 自己执行某个动作,而是会将键盘输入焦点转移到 lineEdit_name 上。这样用户就可以直接在输入框中输入内容,而不需要再用鼠标点击输入框。

因此,QLabel 的 buddy 机制本质上是为表单控件提供快捷访问能力。它的作用不是让标签本身产生交互逻辑,而是通过标签上的助记符,帮助用户快速定位到与该标签关联的输入控件。

结语

那么这就是本篇文章的全部内容,我会持续更新,希望你能够多多关注,如果本文有帮助到你的话,还请三连加关注,你的支持就是我创作的最大动力!

相关推荐
Volunteer Technology1 小时前
Flink编程模型与API(二)
大数据·数据库·flink
流星白龙1 小时前
【MySQL高阶】5.MySQL服务器简介
服务器·mysql·adb
Kapaseker1 小时前
用 Kotlin 构建你的第一个 Agent — 开篇
android·kotlin
流星白龙1 小时前
【MySQL高阶】9.在一台机器上运行多个MySQL实例
数据库·mysql·adb
Rick19931 小时前
MySQL 优化器会选择【最小、最精准、最高效】的索引
数据库·mysql
mN9B2uk171 小时前
MySQL命令行导出数据库
c语言·数据库·mysql
甄心爱学习1 小时前
【项目实训(个人10)】
开发语言·前端·javascript
散峰而望1 小时前
【算法练习】算法练习精选:从 Phone numbers 到 Decrease,覆盖字符串、模拟、图论思维题
数据结构·c++·算法·贪心算法·github·动态规划·图论
右耳朵猫AI1 小时前
Java & JVM技术周刊 2026年第20周
java·开发语言·jvm