【Qt开发】显示类控件(一)-> QLabel

目录

1 -> 概述

1.1 -> 核心使命

1.2 -> 多种能力

1.3 -> 外观与布局

2 -> 核心属性

3 -> 代码示例

3.1 -> 显示不同格式的文本

3.2 -> 显示图片

3.3 -> 文本对齐,自动换行,缩进,边距

3.4 -> 设置伙伴

4 -> 总结


1 -> 概述

Qt 强大的图形界面控件家族中,如果说 QPushButton 是勤劳的实干家,QLineEdit 是信息的收集员,那么 QLabel 无疑就是一位低调而至关重要的信息使者。它是构建用户界面的基石,是连接程序与用户视觉感知的最直接桥梁。尽管其外表简单,但 QLabel 的内在却蕴含着不容小觑的灵活性与力量。

1.1 -> 核心使命

QLabel 最基本、最核心的职责是显示不可编辑的文本或图像。这里的“静态”并非指内容不可变,而是指用户无法像在输入框里那样直接对其进行编辑。它是应用程序向用户展示信息的单向窗口,例如:

  • 窗口标题:说明当前视图或功能的名称。

  • 状态说明:显示诸如“操作成功”、“加载中…”等提示信息。

  • 项目描述:为其他复杂的输入控件(如组合框、滑块)提供文字说明,引导用户操作。

  • 结果展示:输出计算的结果、读取的数据等。

正是通过这些简洁明了的文本,QLabel 为用户提供了理解界面功能和程序状态的上下文,是保证软件易用性的关键元素。

1.2 -> 多种能力

  1. 图像的天然容器:QLabel 可以轻松地显示图片,支持主流的图像格式。从一个小小的图标到一个复杂的示意图,它都能完美承载。开发者可以控制图像的缩放方式,使其适应标签的大小,保持原始比例,或仅仅是居中展示。

  2. 富文本的舞台:除了纯文本,QLabel 还支持 HTML 子集的富文本渲染。这意味着你可以通过简单的 HTML 标签,在标签中实现多彩的文字不同的字体和大小粗体/斜体,甚至超链接。这使得它能够呈现更加丰富和具有层次感的视觉信息,而无需动用更复杂的文本编辑器控件。

  3. 动画与交互的载体:通过将其内容设置为一个动态的 GIF 图片,QLabel 瞬间化身为一个动画播放器,常用于展示加载动画或状态指示动画。此外,虽然它本身不可编辑,但它可以发射信号,例如当用户点击其中的超链接或将鼠标悬停在其上时,为界面增添了一丝交互性。

1.3 -> 外观与布局

  • 对齐方式:开发者可以精确控制内容(文本或图片)在 QLabel 区域内的对齐方式,包括水平方向上的左对齐、居中、右对齐,以及垂直方向上的顶端对齐、居中、底端对齐。这确保了界面元素在任何大小下都能保持整洁和美观。

  • 文本换行:对于长文本,QLabel 提供了自动换行功能,确保所有信息都能完整地呈现给用户,避免被截断。

  • 伙伴关系:QLabel 有一个经典特性——“伙伴”功能。通过为此标签设置一个“伙伴”控件(如 QLineEdit),当用户按下标签中指定的快捷键时,输入焦点便会自动转移到伙伴控件上。这极大地提升了键盘操作的可访问性和效率,是专业桌面应用的标准实践。

2 -> 核心属性

属性说明
textQLabel 中的文本
textFormat

文本的格式

  • Qt::PlainText 纯文本
  • Qt::RichText 富文本(支持 html 标签)
  • Qt::MarkdownText markdown 格式
  • Qt::AutoText 根据文本内容自动决定文本格式
pixmapQLabel 内部包含的图片
scaledContents

设为 true 表示内容自动拉伸填充 QLabel

设为 false 则不会自动拉伸

alignment

对齐方式

可以设置水平和垂直方向如何对齐

wordWrap

设为 true 内部的文本会自动换行

设为 false 内部的文本不会自动换行

indent

设置文本缩进

水平和垂直方向都生效

margin

内部文本和边框之间的边距

不同于 indent,是上下左右四个方向都同时生效

而 indent 最多只是两个方向有效(具体哪两个方向有效取决于 alignment)

openExternalLinks

是否允许打开一个外部链接

(当 QLabel 文本内容包含 url 的时候会用到)

buddy给 QLabel 关联一个 “伙伴”,这样点击 QLabel 时就能对应的伙伴,例如 “伙伴” 如果是一个 QCheckBox,那么该 QCheckBox 就会被选中

3 -> 代码示例

3.1 -> 显示不同格式的文本

1. 在界面上创建3个 QLabel

2. 修改 widget.cpp,设置3个 label 的属性

#include "widget.h"
#include "ui_widget.h"

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

    ui->label->setTextFormat(Qt::PlainText);
    ui->label->setText("这是一段纯文本");

    ui->label_2->setTextFormat(Qt::RichText);
    ui->label_2->setText("<b> 这是一段富文本 <\b>");

    ui->label_3->setTextFormat(Qt::MarkdownText);
    ui->label_3->setText("# 这是Markdown格式");
}

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

3. 运行程序,观察效果

3.2 -> 显示图片

虽然 QPushButton 也可以通过设置图标的方式设置图片,但是并非是一个好的选择。更多时候还是希望通过 QLabel 来作为一个更单纯的显示图片的方式。

1. 在界面上创建一个 QLabel,objectName 为 label

2. 创建 resource.qrc 文件,并把图片导入到 qrc 中

3. 修改 widget.cpp,给 QLabel 设置图片,并设置将窗口填满

观察效果,此时,如果拖动窗口大小,可以看到图片并不会随着窗口大小的改变而同步变化。

为了解决这个问题,可以在 Widget 中重写 resizeEvent 函数。

#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(":/suo.jpg");
    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 函数没有手动调用,但是能在窗口大小变化时被自动调用。

这个过程就是依赖 C++ 中的多态来实现。Qt 框架内部管理着 QWidget 对象表示窗口。在窗口大小发生改变时,Qt 就会自动调用 resizeEvent 函数。

但是由于这个表示窗口的并非是 QWidget,而是 QWidget 的子类,也就是自己写的 Widget。此时虽然是通过父类调用函数,但是实际上执行的是子类的函数(也就是重写后的 resizeEvent)。

此处属于多态机制的一种经典用法。通过上述过程,就可以把自定义的代码,插入到框架内部执行。相当于 “注册回调函数”。

3.3 -> 文本对齐,自动换行,缩进,边距

1. 创建4个 QLabel,objectName 分别是 label 到 label_4

并且在 QFrame 中设置 frameShape 为 Box(使得观察起来更加清晰)

QFrame 是 QLabel 的父类。其中 frameShape 属性用来设置边框性质。

  • QFrame::Box:矩形边框
  • QFrame::Panel:带有可点击区域的面板边框
  • QFrame::WinPanel:Windows 风格的边框
  • QFrame::HLine:水平线边框
  • QFrame::VLine:垂直线边框
  • QFrame::StyledPanel:带有可点击区域的面板边框,但样式取决于窗口主题

2. 编写 widget.cpp,给这四个 label 设置属性

#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::AlignHCenter | Qt::AlignVCenter);

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

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

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

}

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

3. 运行程序,可以看到如下效果

  • 第一个 label 垂直水平居中
  • 第二个 label 设置了 wordWrap,能够自动换行
  • 第三个 label 设置了 Indent,左侧和上方的边框有间距
  • 第四个 label 设置了 margin,四个方向均有间距

3.4 -> 设置伙伴

1. 创建两个 label 和两个 radioButton

objectName 为默认

此处把 label 中的文本设置为 “快捷键 &A” 的形式。

其中 & 后面跟着的字符,就是快捷键。

可以通过 alt + A 的方式来触发该快捷键。

这里的快捷键和 QPushButton 的不同。需要搭配 alt 和单个字母的方式才能触发。

2. 编写 widget.cpp,设置 buddy 属性

当然也可以使用 Qt Designer 直接设置

#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;
}

3. 运行程序,可以看到,按下快捷键 alt + A 或者 alt + B,即可选中对应的选项

4 -> 总结

总而言之,QLabel 远不止是一个简单的标签。它是一个文本渲染器、一个图像查看器、一个富文本编辑器,甚至是一个动画窗口。它是 Qt 控件工具箱中最基础、最常用,也最被低估的组件之一。理解并善用 QLabel 的多功能特性,是打造出美观、信息丰富且用户友好的 Qt 应用程序的第一步。


感谢各位大佬支持!!!

互三啦!!!

// 创建用户名图标标签 QLabel *userIconLabel = new QLabel(ui->leUserName); // 修改父控件 userIconLabel->setPixmap(QPixmap(":/PkuCfws_AI/resource/frmLogin_user.png").scaled(18, 21, Qt::KeepAspectRatio)); userIconLabel->setAlignment(Qt::AlignCenter); userIconLabel->setFixedSize(30, ui->leUserName->height()); ui->leUserName->setTextMargins(userIconLabel->width() + 5, 0, 0, 0); userIconLabel->move(ui->leUserName->pos().x(), ui->leUserName->pos().y()); // 创建密码图标标签 QLabel *pwdIconLabel = new QLabel(ui->lePassWord); // 修改父控件 pwdIconLabel->setPixmap(QPixmap(":/PkuCfws_AI/resource/frmLogin_userPassword.png").scaled(20, 20, Qt::KeepAspectRatio)); pwdIconLabel->setAlignment(Qt::AlignCenter); pwdIconLabel->setFixedSize(30, ui->lePassWord->height()); ui->lePassWord->setTextMargins(pwdIconLabel->width() + 5, 0, 30, 0); pwdIconLabel->move(ui->lePassWord->pos().x(), ui->lePassWord->pos().y()); // 创建密码框右侧的按钮 QPushButton *rightButton = new QPushButton(ui->lePassWord); rightButton->setIcon(QIcon(":/PkuCfws_AI/resource/frmLogin_password2.png")); rightButton->setFixedSize(30, ui->lePassWord->height()); rightButton->setFlat(true); rightButton->move(ui->lePassWord->pos().x() + ui->lePassWord->width() - rightButton->width(), ui->lePassWord->pos().y()); connect(rightButton, &QPushButton::clicked, this, [this](){ qDebug() << "Right button clicked"; }); // 调整现有密码显示/隐藏按钮的位置 ui->pbDisplayPassword->move(ui->lePassWord->pos().x() + ui->lePassWord->width() - ui->pbDisplayPassword->width() - 40, ui->lePassWord->pos().y()); ui->pbHidePassword->move(ui->lePassWord->pos().x() + ui->lePassWord->width() - ui->pbHidePassword->width() - 40, ui->lePassWord->pos().y());将userIconLabel和pwdIconLabel设置到父对象的lineedit左侧的上下居中位置,rightButton设置到父对象的右侧位置
08-19
<think>我们想要实现的效果是:在QLineEdit的左侧放置QLabel图标(上下居中),右侧放置个QPushButton(上下居中)。这可以通过以下两种方式实现: ### 方法1:使用布局管理器(推荐) 创建个水平布局,将QLabel、QLineEdit和QPushButton依次加入。设置布局的边距和间距,并确保控件在布局中垂直居中。 ```cpp // 创建个容器Widget来放置这三个控件 QWidget *container = new QWidget(this); QHBoxLayout *layout = new QHBoxLayout(container); layout->setContentsMargins(0, 0, 0, 0); // 移除容器的边距 layout->setSpacing(0); // 设置控件之间的间距为0 // 创建图标标签 QLabel *iconLabel = new QLabel; iconLabel->setPixmap(QPixmap(":/icons/user.png").scaled(20, 20)); // 设置图标并缩放 iconLabel->setAlignment(Qt::AlignCenter); // 图标在标签内居中 // 创建输入框 QLineEdit *lineEdit = new QLineEdit; lineEdit->setPlaceholderText("请输入账号"); // 创建右侧按钮 QPushButton *button = new QPushButton; button->setIcon(QIcon(":/icons/eye.png")); // 将控件添加到布局中 layout->addWidget(iconLabel); layout->addWidget(lineEdit); layout->addWidget(button); // 设置布局中控件的对齐方式(垂直居中) layout->setAlignment(iconLabel, Qt::AlignVCenter); layout->setAlignment(button, Qt::AlignVCenter); // 设置容器的大小策略(可选) container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // 将容器添加到父布局中(假设父布局是垂直布局,位于某个父Widget上) parentLayout->addWidget(container); ``` ### 方法2:手动调整位置(不推荐,但有时需要) 如果无法使用布局管理器(例如在自定义绘制中),可以重写`resizeEvent`来手动调整位置。但这种方法更复杂且容易出错。 ```cpp void YourWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); // 假设lineEdit已经设置好,且iconLabel和button是它的子控件 int iconWidth = 30; int buttonWidth = 30; // 设置图标标签的位置(左侧,上下居中) int y = (ui->lineEdit->height() - iconLabel->height()) / 2; iconLabel->move(ui->lineEdit->x(), ui->lineEdit->y() + y); // 设置按钮的位置(右侧,上下居中) y = (ui->lineEdit->height() - button->height()) / 2; button->move(ui->lineEdit->x() + ui->lineEdit->width() - buttonWidth, ui->lineEdit->y() + y); // 调整输入框的文本边距,避免文本与图标重叠 ui->lineEdit->setTextMargins(iconWidth, 0, buttonWidth, 0); } ``` ### 注意事项: 1. **图标尺寸**:使用`scaled`调整图标大小,确保其适合输入框的高度。 2. **边距调整**:在方法2中,必须设置`setTextMargins`,否则输入文本会与图标重叠。 3. **事件处理**:如果右侧按钮需要响应事件(如密码显示/隐藏),请连接其`clicked`信号。 4. **样式表**:如果使用样式表,注意设置背景透明,避免覆盖。 ### 示例:密码显示/隐藏按钮 ```cpp // 在方法1的代码基础上,添加按钮事件 connect(button, &QPushButton::clicked, [lineEdit, button]() { if (lineEdit->echoMode() == QLineEdit::Password) { lineEdit->setEchoMode(QLineEdit::Normal); button->setIcon(QIcon(":/icons/eye_closed.png")); } else { lineEdit->setEchoMode(QLineEdit::Password); button->setIcon(QIcon(":/icons/eye_open.png")); } }); ``` ### 引用说明 以上方法参考了Qt布局管理的基本原理[^2]和控件定位技术[^3]。 §§相关问题§§ 1. Qt布局管理器有哪些类型?各自适用什么场景? 2. 如何实现QLineEdit的密码显示/隐藏功能? 3. 如何自定义QPushButton的图标和样式? 4. 如何处理Qt控件重叠或覆盖的问题?</think>### Qt5 C++ 设置 QLabel 图标在 QLineEdit 左侧居中 + QPushButton 在右侧 在 Qt 中实现图标在输入框左侧居中、按钮在右侧的布局,可以通过以下两种方法实现: #### 方法1:使用布局管理器(推荐) ```cpp // 创建水平布局容器 QWidget *container = new QWidget(this); QHBoxLayout *hLayout = new QHBoxLayout(container); hLayout->setContentsMargins(0, 0, 0, 0); // 移除边距 hLayout->setSpacing(5); // 控件间距 // 左侧图标 (QLabel) QLabel *iconLabel = new QLabel; iconLabel->setPixmap(QPixmap(":/icons/user.png").scaled(20, 20, Qt::KeepAspectRatio)); iconLabel->setAlignment(Qt::AlignCenter); iconLabel->setFixedSize(30, 30); // 固定尺寸确保居中 // 输入框 (QLineEdit) QLineEdit *lineEdit = new QLineEdit; lineEdit->setPlaceholderText("请输入内容"); lineEdit->setMinimumHeight(30); // 设置最小高度 // 右侧按钮 (QPushButton) QPushButton *actionButton = new QPushButton; actionButton->setIcon(QIcon(":/icons/eye.png")); actionButton->setFixedSize(30, 30); // 固定尺寸 // 添加到布局 hLayout->addWidget(iconLabel); hLayout->addWidget(lineEdit); hLayout->addWidget(actionButton); // 设置对齐方式 - 关键步骤! hLayout->setAlignment(iconLabel, Qt::AlignVCenter); // 垂直居中 hLayout->setAlignment(actionButton, Qt::AlignVCenter); // 垂直居中 // 将容器添加到父布局 parentLayout->addWidget(container); ``` #### 方法2:自定义定位(不使用布局) ```cpp // 在构造函数中 ui->setupUi(this); // 创建图标标签 QLabel *iconLabel = new QLabel(this); iconLabel->setPixmap(QPixmap(":/icons/user.png").scaled(20, 20, Qt::KeepAspectRatio)); iconLabel->setAlignment(Qt::AlignCenter); // 创建右侧按钮 QPushButton *actionButton = new QPushButton(this); actionButton->setIcon(QIcon(":/icons/eye.png")); // 计算位置 int inputHeight = ui->lineEdit->height(); int iconY = ui->lineEdit->y() + (inputHeight - iconLabel->height()) / 2; int buttonY = ui->lineEdit->y() + (inputHeight - actionButton->height()) / 2; // 设置位置 iconLabel->move(ui->lineEdit->x(), iconY); actionButton->move(ui->lineEdit->x() + ui->lineEdit->width() - actionButton->width(), buttonY); // 设置输入框边距防止重叠 ui->lineEdit->setTextMargins(iconLabel->width() + 5, 0, actionButton->width() + 5, 0); ``` #### 关键点说明: 1. **垂直居中技巧**: - 使用布局管理器时:`setAlignment(Qt::AlignVCenter)` - 手动定位时:`y = lineEdit->y() + (lineEditHeight - controlHeight)/2` 2. **尺寸控制**: ```cpp // 固定高度确保垂直居中 iconLabel->setFixedHeight(lineEdit->height()); actionButton->setFixedHeight(lineEdit->height()); ``` 3. **边距处理**: ```cpp // 防止文本与图标重叠 lineEdit->setTextMargins(iconLabel->width() + 5, 0, actionButton->width() + 5, 0); ``` 4. **样式优化**: ```cpp // 设置透明背景 iconLabel->setStyleSheet("background: transparent;"); actionButton->setStyleSheet("QPushButton { border: none; background: transparent; }"); ``` #### 完整示例 - 密码输入框: ```cpp // 创建密码输入组件 QWidget* createPasswordInput() { QWidget *container = new QWidget; QHBoxLayout *layout = new QHBoxLayout(container); layout->setContentsMargins(0, 0, 0, 0); // 锁图标 QLabel *lockIcon = new QLabel; lockIcon->setPixmap(QPixmap(":/icons/lock.png").scaled(20, 20)); lockIcon->setFixedSize(30, 30); // 密码输入框 QLineEdit *passwordEdit = new QLineEdit; passwordEdit->setEchoMode(QLineEdit::Password); passwordEdit->setPlaceholderText("输入密码"); passwordEdit->setMinimumHeight(35); // 显示/隐藏按钮 QPushButton *toggleButton = new QPushButton; toggleButton->setIcon(QIcon(":/icons/eye-closed.png")); toggleButton->setFixedSize(30, 30); toggleButton->setCheckable(true); // 连接信号 QObject::connect(toggleButton, &QPushButton::toggled, [=](bool checked){ passwordEdit->setEchoMode(checked ? QLineEdit::Normal : QLineEdit::Password); toggleButton->setIcon(QIcon(checked ? ":/icons/eye-open.png" : ":/icons/eye-closed.png")); }); // 添加到布局 layout->addWidget(lockIcon); layout->addWidget(passwordEdit); layout->addWidget(toggleButton); // 设置垂直居中 layout->setAlignment(lockIcon, Qt::AlignVCenter); layout->setAlignment(toggleButton, Qt::AlignVCenter); return container; } ``` 这种方法确保了图标在输入框左侧垂直居中,按钮在右侧垂直居中,且布局能自适应不同屏幕尺寸[^2][^3]。
评论 82
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值