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

结语

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

相关推荐
alexhilton10 小时前
使用Android Archive进行打包
android·kotlin·android jetpack
badhope12 小时前
做了几年安卓开发,这些坑我帮你踩过了
android·android studio
xcyxiner12 小时前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner1 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner1 天前
DicomViewer (添加模型类)3
qt
xcyxiner2 天前
DicomViewer (目录调整) 2
qt
xcyxiner2 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
倔强的石头_2 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
云技纵横2 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
沉默王二2 天前
面试官:RAG 不用向量数据库,用 MySQL 硬扛?我:100 万向量不是很轻松?
mysql·面试·ai编程