
🎬 个人主页 :艾莉丝努力练剑
❄专栏传送门 :《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》
《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬 艾莉丝的简介:

文章目录
- [1 ~> 控件概述](#1 ~> 控件概述)
-
- [1.1 Widget](#1.1 Widget)
- [1.2 关于控件体系的发展](#1.2 关于控件体系的发展)
-
- [1.2.1 第一阶段](#1.2.1 第一阶段)
- [1.2.2 第二阶段](#1.2.2 第二阶段)
- [1.2.3 第三阶段](#1.2.3 第三阶段)
- [2 ~> QWidget核心属性](#2 ~> QWidget核心属性)
-
- [2.1 核心属性概览](#2.1 核心属性概览)
- [2.2 一些比较重要比较常用的属性](#2.2 一些比较重要比较常用的属性)
-
- [2.2.1 enabled](#2.2.1 enabled)
- [2.2.2 geometry](#2.2.2 geometry)
-
- [2.2.2.1 相关API](#2.2.2.1 相关API)
- [2.2.3 windowTitle](#2.2.3 windowTitle)
- [2.2.4 windowIcon](#2.2.4 windowIcon)
- [2.2.5 windowOpacity](#2.2.5 windowOpacity)
- [2.2.6 cursor](#2.2.6 cursor)
- [2.2.7 font](#2.2.7 font)
- [2.2.8 toolTip](#2.2.8 toolTip)
- [2.2.9 focusPolicy](#2.2.9 focusPolicy)
- [2.2.10 styleSheet](#2.2.10 styleSheet)
- 结尾

1 ~> 控件概述
1.1 Widget
Widget是Qt中的核心概念。
- 英文原义是"小部件",我们此处也把它翻译为 "控件"。
控件是构成一个图形化界面的基本要素。

像上述示例中的:按钮、列表视图、树形视图、单行输入框、多行输入框、滚动条、下拉框 等,都可以称为 "控件"。
Qt作为一个成熟的GUI开发框架,内置了大量的常用控件。
- 这一点在
Qt Designer中就可以看到端倪。
并且Qt也提供了 "自定义控件" 的能力,可以让程序猿在现有控件不能满足需求的时候,对现有控件做出扩展,或者手搓出新的控件。

综上,学习
Qt,其中一个很重要的任务 就是熟悉并掌握Qt内置的常用控件。这些控件对于我们快速开发出符合需求的界面,是至关重要的。
1.2 关于控件体系的发展
- 控件是
GUI开发中的通用概念,不仅仅局限在Qt中。
1.2.1 第一阶段
完全没有控件,此时需要通过一些绘图API手动的绘制出按钮或者输入框等内容,代码编写繁琐。
例如:文曲星的Lava平台开发.

1.2.2 第二阶段
只包含粗略的控件,只是提供了按钮、输入框、单选框、复选框等最常用的控件。
例如html的原生控件。
一则老新闻:

1.2.3 第三阶段
更完整的控件体系,基本可以覆盖到GUI开发中的大部分场景。
例如早期的 MFC、VB、C++ Builder、Qt、Delphi,后来的Android SDK、Java FX、前端的各种UI库等。
下面艾莉丝给大家推荐一个网站:Element-ui
- 链接: Element

- 上图是前端中的
Element-ui中的控件概览,无论是丰富程度还是颜值,都比Qt自带的控件更胜一筹。
2 ~> QWidget核心属性
在Qt中,使用QWidget类表示 "控件" 。像按钮、视图、输入框、滚动条 等具体的控件类,都是继承自QWidget。
可以说,QWidget 中就包含了Qt整个控件体系中,通用的部分。
在Qt Designer中,随便拖一个控件过来,选中该控件,即可在右下方看到QWidget中的属性。

这些属性既可以通过Qt Designer会直接修改,也可以通过代码的方式修改。
这些属性的具体含义,在Qt Assistant中均有详细介绍。
在
Qt Assistant中搜索QWidget,即可找到对应的文档说明。或者在
Qt Creator代码中,选中QWidget,按F1也可。
2.1 核心属性概览
下列表格列出了QWidget中的属性及其作用------
| 属性 | 作用 |
|---|---|
| enabled | 设置控件是否可使用。true 表示可用,false 表示禁用。 |
| geometry | 位置和尺寸。包含 x, y, width, height 四个部分。 其中坐标是以父元素为参考进行设置的。 |
| windowTitle | 设置 widget 标题 |
| windowIcon | 设置 widget 图标 |
| windowOpacity | 设置 widget 透明度 |
| cursor | 鼠标悬停时显示的图标形状。 是普通箭头,还是沙漏,还是十字等形状。 在 Qt Designer 界面中可以清楚看到可选项。 |
| font | 字体相关属性。 涉及到字体家族、字体大小、粗体、斜体、下划线等等样式。 |
| toolTip | 鼠标悬停在 widget 上会在状态栏中显示的提示信息。 |
| toolTipDuring | toolTip 显示时的持续时间。 |
| statusTip | Widget 状态发生改变时显示的提示信息(比如按钮被按下等)。 |
| whatsThis | 鼠标悬停在 widget 上时会以当前焦点(显示在一个弹出的窗口中)。 |
| styleSheet | 允许使用 CSS 来设置 widget 中的样式。 Qt 中支持的样式非常丰富,对于前端开发人员上手是非常友好的。 |
| focusPolicy | 该 widget 如何获取到焦点。 - Qt::NoFocus: 控件不参与焦点管理,即无法通过键盘或鼠标获取焦点 - Qt::TabFocus: 控件可以通过 Tab 键获得焦点 - Qt::ClickFocus: 控件可以通过鼠标点击获得焦点 - Qt::StrongFocus: 控件可以通过键盘和鼠标获得焦点 - Qt::WheelFocus: 控件可以通过鼠标滚轮获得焦点(在某些平台或样式中可能不可用) |
| contextMenuPolicy | 上下文菜单的显示策略。 - Qt::DefaultContextMenu: 默认的上下文菜单策略,用户可以通过鼠标右键或键盘快捷键触发上下文菜单 - Qt::NoContextMenu: 禁用上下文菜单,即使用户点击鼠标右键也不会显示菜单 - Qt::PreventContextMenu: 防止控件显示上下文菜单,即使用户点击鼠标右键也不会显示菜单 - Qt::ActionsContextMenu: 将上下文菜单替换为控件的"动作"菜单,用户可以通过鼠标右键或键盘快捷键触发这个菜单 |
| locale | 设置语言和区域。 |
| acceptDrops | 该控件是否接受拖放操作。 如果设置为 true,那么该控件就可以接收来自其他部件的拖放操作。当一个部件被拖放到该控件上时,该部件会接收到相应的拖放事件(如 dropEvent)。 如果设置为 false,那么该部件将不会接收到任何拖放事件。 |
| minimumSize | 控件的最小尺寸。包含最小宽度和最小高度。 |
| maximumSize | 控件的最大尺寸。包含最大宽度和最大高度。 |
| sizePolicy | 尺寸策略。设置控件在布局管理器中的缩放方式。 |
| windowModality | 指定窗口是否具有"模态"行为。 |
| sizeIncrement | 拖动窗口大小的增量单位。 |
| baseSize | 窗口的基础大小,用来搭配 sizeIncrement 调整组件尺寸是计算组件应该调整到的合适的值。 |
| palette | 调色板。可以设置 widget 的颜色风格。 |
| mouseTracking | 是否要跟踪鼠标移动事件。 如果设为 true,表示需要跟踪,则鼠标划过的时候该 widget 就能持续收到鼠标移动事件。 如果设为 false,表示不需要跟踪,则鼠标划过的时候 widget 不能收到鼠标移动事件,只能收到鼠标按下或者释放的事件。 |
| tabletTracking | 是否要跟踪触摸屏的移动事件。 如果设为 true,表示需要跟踪,则鼠标划过的时候该 widget 能够持续收到鼠标移动事件。 如果设为 false,表示不需要跟踪,则鼠标划过的时候 widget 不能收到鼠标移动事件,只能收到鼠标按下或者释放的事件。 |
接下来我们会介绍其中一些比较重要比较常用的属性,并附有代码示例。
- 注意: 本章节的每个代码示例都是创建了单独的Qt项目,课件中省略了创建项目的具体步骤。
2.2 一些比较重要比较常用的属性
2.2.1 enabled
| API | 说明 |
|---|---|
| isEnabled() | 获取到控件的可用状态。 |
| setEnabled | 设置控件是否可使用。true表示可用,false表示禁用。 |
- 所谓 **"禁用"**指的是该控件不能接收任何用户的输入事件,并且外观上往往是灰色的。
- 如果一个
widget被禁用,则该widget的子元素也被禁用。
代码示例: 使用代码创建一个禁用状态的按钮。
widget.cpp
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* btn = new QPushButton(this);
btn->setText("这是个被禁⽤的按钮");
btn->setEnabled(false);
}
运行程序,可以看到按钮处于灰色状态,无法被点击。

代码示例: 通过按钮2切换按钮1的禁用状态。
1)使用Qt Designer拖两个按钮到Widget中。

两个按钮的objectName分别为 pushButton 和pushButton_2。

cpp
class Ui_Widget
{
public:
QPushButton *pushButton;
QPushButton *pushButton_2;
// . . . . . .
};
2)生成两个按钮的 slot 函数.
- 使用
isEnabled获取当前按钮的可用状态。 - 使用
setEnabled修改按钮的可用状态。此处是直接针对原来的可用状态进行取反后设置。
cpp
void Widget::on_pushButton_clicked()
{
qDebug() << "按下按钮";
}
void Widget::on_pushButton_2_clicked()
{
bool flag = this->ui->pushButton->isEnabled();
this->ui->pushButton->setEnabled(!flag);
}
运行程序,可以看到,初始情况下,上面的按钮是可用状态。
点击下方按钮,即可使上方按钮被禁用;再次点击下方按钮,上方按钮就会解除禁用,(禁用状态的按钮为灰色,且不可点击)。

在Qt Designer中创建按钮的时候,可以设置按钮的初始状态是"可用"还是"禁用"。
如果把enabled这一列的对钩去掉,则按钮的初始状态就是"禁用"状态。

2.2.2 geometry
位置和尺寸,其实是四个属性的统称:
-
x横坐标 -
y纵坐标 -
width宽度 -
height高度

但是实际开发中,我们并不会直接使用这几个属性,而是通过一系列封装的方法来获取 / 修改。
- 对于
Qt的坐标系,不要忘记是一个"左手坐标系"其中坐标系的原点是当前元素的父元素的左上角。

| API | 说明 |
|---|---|
| geometry() | 获取控件的位置和尺寸。返回一个 QRect 对象,包含 x、y、width、height,其中 (x, y) 为左上角坐标。 |
| setGeometry() | 设置控件的位置和尺寸。该函数有两个重载版本: • setGeometry(QRect):直接传入一个 QRect 对象; • setGeometry(int x, int y, int width, int height):分别指定左上角坐标和宽高。 |

| API | 说明 |
|---|---|
| geometry() | 获取控件的位置和尺寸。返回一个 QRect,包含 x、y、width、height,其中 (x, y) 为左上角坐标。 |
| setGeometry(QRect) | 设置控件的位置和尺寸,通过 QRect 对象指定。 |
| setGeometry(int x, int y, int width, int height) | 设置控件的位置和尺寸,分别通过左上角坐标 (x, y) 以及宽度和高度指定。 |
代码示例: 控制按钮的位置。
1)在界面中拖五个按钮
五个按钮的 objectName分别为pushButton_target、pushButton_up、pushButton_down、pushButton_left、pushButton_right。
五个按钮的初始位置和大小都随意。

2)在widget.cpp 中编写四个按钮的slot函数
cpp
void Widget::on_pushButton_up_clicked()
{
QRect rect = ui->pushButton_target->geometry();
rect.setY(rect.y() - 5);
ui->pushButton_target->setGeometry(rect);
}
void Widget::on_pushButton_down_clicked()
{
QRect rect = ui->pushButton_target->geometry();
rect.setY(rect.y() + 5);
ui->pushButton_target->setGeometry(rect);
}
void Widget::on_pushButton_left_clicked()
{
QRect rect = ui->pushButton_target->geometry();
rect.setX(rect.x() - 5);
ui->pushButton_target->setGeometry(rect);
}
void Widget::on_pushButton_right_clicked()
{
QRect rect = ui->pushButton_target->geometry();
rect.setX(rect.x() + 5);
ui->pushButton_target->setGeometry(rect);
}
运行程序,可以看到,按下下方的四个按钮,就会控制target的左上角的位置.对应的按钮整个尺寸也会发生改变。
- 上述代码中我们是直接设置的
QRect中的x,y。实际上QRect内部是存储了左上和右下两个点的坐标,再通过这两个点的坐标差值计算长宽。- 单纯修改左上坐标就会引起整个矩形的长宽发生改变。

如果想让整个按钮都移动,可以改成下列代码:
cpp
void Widget::on_pushButton_up_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x(), rect.y() - 5, rect.width(),
rect.height());
}
void Widget::on_pushButton_down_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5, rect.width(),
rect.height());
}
void Widget::on_pushButton_left_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x() - 5, rect.y(), rect.width(),
rect.height());
}
void Widget::on_pushButton_right_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(),
rect.height());
}
- 上述代码使用
move方法也是可以的。
代码示例: 一个表白程序
1)往界面上拖拽两个按钮和一个Label。
Label 的 objectName为pushButton_accept和pushButton_reject,label的objectName为label。
控件中文本如下图所示------

2)在widget.cpp 中添加slot函数
cpp
void Widget::on_pushButton_accept_clicked()
{
ui->label->setText("⼥神快来嘴⼀个! mua~~");
}
void Widget::on_pushButton_reject_pressed()
{
// 获取窗⼝的宽度和⾼度
int width = this->geometry().width();
int height = this->geometry().height();
// 重新⽣成按钮的位置.
int x = rand() % width;
int y = rand() % height;
// 设置新的位置
ui->pushButton_reject->move(x, y);
}
运行程序,可以看到,当点击 "残忍拒绝" 时,按钮就跑了。

上述代码使用的是pressed,鼠标按下事件。如果使用mouseMoveEvent,会更狠一些,只要鼠标移动过来,按钮就跑了。
对应的代码更麻烦一些(需要自定义类继承自QPushButton,重写mouseMoveEvent方法),此处暂时不展开。


2.2.2.1 相关API
相关API及其详细说明如下所示:
| API | 说明 |
|---|---|
| x() | 获取横坐标 计算时包含 window frame |
| y() | 获取纵坐标 计算时包含 window frame |
| pos() | 返回 QPoint 对象,里面包含 x(), y(), setX(), setY() 等方法。 计算时包含 window frame |
| frameSize() | 返回 QSize 对象,里面包含 width(), height(), setWidth(), setHeight() 等方法。 计算时包含 window frame |
| frameGeometry() | 返回 QRect 对象。QRect 相当于 QPoint 和 QSize 的结合体。可以获取 x, y, width, size。 计算时包含 window frame 对象。 |
| width() | 获取宽度 计算时不包含 window frame |
| height() | 获取高度 计算时不包含 window frame |
| size() | 返回 QSize 对象,里面包含 width(), height(), setWidth(), setHeight() 等方法。 计算时不包含 window frame |
| rect() | 返回 QRect 对象。QRect 相当于 QPoint 和 QSize 的结合体。可以获取并设置 x, y, width, size。 计算时不包含 window frame 对象。 |
| geometry() | 返回 QRect 对象。QRect 相当于 QPoint 和 QSize 的结合体。可以获取 x, y, width, size。 计算时不包含 window frame 对象。 |
| setGeometry() | 直接设置窗口的位置和尺寸。可以设置 x, y, width, height,或者 QRect 对象。 计算时不包含 window frame 对象。 |

代码示例: 感受geometry和 frameGeometry的区别。
1)在界面上放置一个按钮

2)在按钮的slot函数中,编写代码:
cpp
void Widget::on_pushButton_clicked()
{
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << rect1;
qDebug() << rect2;
}
3)在构造函数中,也添加同样的代码
cpp
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << rect1;
qDebug() << rect2;
}
执行程序,可以看到,构造函数中,打印出的geometry和frameGeometry是相同的。
但是在点击按钮时,打印的geometry和 frameGeometry则存在差异。


2.2.3 windowTitle


代码示例: 设置窗口标题
修改 widget.cpp
cpp
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置窗⼝标题
this->setWindowTitle("这是标题");
}
执行结果:

2.2.4 windowIcon

同windowTitle,上述操作仅针对顶层widget有效。
代码示例: 设置窗口图标
1)先在D盘中放一个图片,名字为 rose.jpg

2)修改 widget.cpp
cpp
#include <QIcon>
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建图标对象
QIcon icon("d:/rose.jpg");
// 设置图标
this->setWindowIcon(icon);
}
注意: Windows下路径的分隔符可以使用/也可以使用\,但是如果在字符串中使用\,需要写作转义字符的形式\\,因此我们还是更推荐使用/。
3)运行程序,可以看到窗口图标已经成为上述图片

于此同时,程序在任务栏中的图表也发生改变------



对于Qt程序来说,当前工作目录可能是变化的。比如通过Qt Creator运行的程序,当前工作目录是项目的构建目录;直接双击exe运行,工作目录则是exe所在目录。
所谓构建目录,是和Qt项目并列的,专门用来放生成的临时文件和最终exe的目录。

代码示例: 获取当前的工作目录
1)在界面上创建一个比较大的label,确保能把路径显示完整。objectName使用默认的label即可。

2)修改widget.cpp
- 使用
QDir::currentPath()即可获取到当前工作目录
cpp
#include <QDir>
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 获取到当前⼯作⽬录
QString currentDir = QDir::currentPath();
// 设置⼯作⽬录到 label 中.
ui->label->setText(currentDir);
}
3)直接在QtCreator中执行程序,可以看到当前工作目录是项目的构建目录。

4)进入上述构建目录,把里面的exe拷贝到其他目录中,比如D:中,再次执行程序,可以看到当前工作目录已经发生改变。

- 要想直接能双击exe运行,需要先把Qt的路径添加到path环境变量中,否则会提示找不到动态库。 这一点我们最开始搭建开发环境的时候已经操作过,此处不再赘述。
注意,上述构建目录是随时可删除的,比如点击菜单栏中的 "构建"~>"清理项目",就会把这个目录中的内容清空掉。
因此如果我们把图片文件放到构建目录中,可能在不小心删除后就丢失了,我们还是希望能够把图片和源代码放到一起,并且使我们的程序无论拷贝到任何位置中都能正确使用图片。
Qt使用qrc机制帮我们自动完成了上述工作,更方便的来管理项目依赖的静态资源。

代码示例: 通过qrc管理图片作为图标
1)右键项目,创建一个Qt Resource File(qrc文件),文件名随意起(不要带中文),此处叫做resource.qrc。

2)在qrc 编辑器中,添加前缀。

此处我们前缀设置成/即可。
- 所谓的前缀,可以理解成"目录",这个前缀决定了后续我们如何在代码中访问资源。
3)在资源编辑器中,点击add Files添加资源文件.此处我们需要添加的是rose.jpg

- 注意: 添加的文件必须是在qrc文件的同级目录,或者同级目录的子目录中,因此我们需要把之前D盘中的 rose.jpg复制到上述目录中。
添加完毕后,可以在资源编辑器中看到添加好的文件。

4)在代码中使用 rose.jpg
编辑widget.cpp
cpp
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 访问到 rose.jpg 资源
QIcon icon(":/rose.jpg");
// 设置图标
this->setWindowIcon(icon);
}

5)运行程序,可以看到图标已经能正确设置。

接下来,我们可以进入到项目的构建目录,可以看到,目录中多了一个qrc_resource.cpp文件.直接打开这个文件,可以看到类似如下代码:
bash
static const unsigned char qt_resource_data[] = {
// D:/project/ke/qt/DemoCode/DemoWindowIconQrc/rose.jpg
0x0,0x0,0x33,0x2,
0xff,
0xd8,0xff,0xe0,0x0,0x10,0x4a,0x46,0x49,0x46,0x0,0x1,0x1,0x0,0x0,0x1,0x0,
0x1,0x0,0x0,0xff,0xfe,0x0,0x3b,0x43,0x52,0x45,0x41,0x54,0x4f,0x52,0x3a,0x20,
0x67,0x64,0x2d,0x6a,0x70,0x65,0x67,0x20,0x76,0x31,0x2e,0x30,0x20,0x28,0x75,0x73
,
0x69,0x6e,0x67,0x20,0x49,0x4a,0x47,0x20,0x4a,0x50,0x45,0x47,0x20,0x76,0x36,0x32
,
0x29,0x2c,0x20,0x71,0x75,0x61,0x6c,0x69,0x74,0x79,0x20,0x3d,0x20,0x39,0x35,0xa,
0xff,0xdb,0x0,0x43,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x2,0x1,0x1,0x1,0x2,
0x2,0x2,0x2,0x2,0x4,0x3,0x2,0x2,0x2,0x2,0x5,0x4,0x4,0x3,0x4,0x6,
0x5,0x6,0x6,0x6,0x5,0x6,0x6,0x6,0x7,0x9,0x8,0x6,0x7,0x9,0x7,0x6,
0x6,0x8,0xb,0x8,0x9,0xa,0xa,0xa,0xa,0xa,0x6,0x8,0xb,0xc,0xb,0xa,
0xc,0x9,0xa,0xa,0xa,0xff,0xdb,0x0,0x43,0x1,0x2,0x2,0x2,0x2,0x2,0x2,
// .............
上述代码其实就是通过unsignedchar数组,把rose.jpg中的每个字节都记录下来.这些代码会被编译到exe中,后续无论exe被复制到哪个目录下,都确保能够访问到该图片资源。

2.2.5 windowOpacity

代码示例: 调整窗口透明度
1)在界面上拖放两个按钮,分别用来增加不透明度和减少不透明度,objectName分别为pushButton_add和pushButton_sub

2)编写wdiget.cpp,编写两个按钮的slot函数
- 点击
pushButton_sub会减少不透明度,也就是窗口越来越透明。 - 点击
pushButton_add会增加不透明度,窗口会逐渐恢复。
cpp
void Widget::on_pushButton_add_clicked()
{
float opacity = this->windowOpacity();
if (opacity >= 1.0) {
return;
}
qDebug() << opacity;
opacity += 0.1;
this->setWindowOpacity(opacity);
}
void Widget::on_pushButton_sub_clicked()
{
float opacity = this->windowOpacity();
if (opacity <= 0.0) {
return;
}
qDebug() << opacity;
opacity -= 0.1;
this->setWindowOpacity(opacity);
}
3)执行程序,可以看到,点击了几下-之后,就可以透过窗口看到后面的猫猫头了,点击+又会逐渐恢复。

同时控制台中也可以看到opacity数值的变化。

注意,C++中float类型遵守 IEEE754标准 ,因此在进行运算的时候会有一定的精度误差.因此1 - 0.1的数值并非是0.9。
2.2.6 cursor

代码示例: 在QtDesigner中设置按钮的光标
1)在界面中创建一个按钮。

2)直接在右侧属性编辑区修改cursor属性为 "等待":

3)运行程序,鼠标悬停到按钮上,即可看到光标的变化。
- 截图无法截到鼠标光标,同学们自行运行验证。
代码示例: 通过代码设置按钮的光标
1)编写 widget.cpp
- 其中
Qt::WaitCursor就是自带的沙漏形状的光标。
cpp
#include <QPushButton>
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建按钮
QPushButton* button = new QPushButton(this);
button->resize(100, 50);
button->move(100, 100);
button->setText("这是⼀个按钮");
// 设置按钮的 cursor
button->setCursor(QCursor(Qt::WaitCursor));
}
系统内置的光标形状如下:
- Ctrl +左键点击
Qt::WaitCursor跳转到源码即可看到。
bash
enum CursorShape {
ArrowCursor,
UpArrowCursor,
CrossCursor,
WaitCursor,
IBeamCursor,
SizeVerCursor,
SizeHorCursor,
SizeBDiagCursor,
SizeFDiagCursor,
SizeAllCursor,
BlankCursor,
SplitVCursor,
SplitHCursor,
PointingHandCursor,
ForbiddenCursor,
WhatsThisCursor,
BusyCursor,
OpenHandCursor,
ClosedHandCursor,
DragCopyCursor,
DragMoveCursor,
DragLinkCursor,
LastCursor = DragLinkCursor,
BitmapCursor = 24,
CustomCursor = 25
}
2)运行程序,观察效果。
- 截图无法截到鼠标光标,同学们自行运行验证。
代码示例: 自定义鼠标光标
Qt自带的光标形状有限,我们也可以自己找个图片,做成鼠标的光标,比如我们有请滑稽老铁------

1)创建qrc资源文件,添加前缀/,并加入huaji.png。



2)编写widget.cpp
cpp
#include <QPixmap>
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建⼀个位图对象, 加载⾃定义光标图⽚
QPixmap pixmap(":/huaji.png");
// 缩放图⽚为 64 * 64 的尺⼨.
pixmap = pixmap.scaled(64, 64);
// 创建 QCursor 对象, 并指定 "热点" 为 (2, 2) 坐标位置.
// 所谓 "热点" 就是⿏标点击时⽣效的位置.
QCursor cursor(pixmap, 2, 2);
// 设置光标
this->setCursor(cursor);
}
3)运行程序,观察效果
截图无法截到鼠标光标,请uu们自行运行验证。
2.2.7 font

关于QFont
| 属性 | 说明 |
|---|---|
| family | 字体家族。比如"楷体","宋体","微软雅黑"等。 |
| pointSize | 字体大小 |
| weight | 字体粗细。以数值方式表示粗细程度取值范围为 [0, 99],数值越大,越粗。 |
| bold | 是否加粗。设置为 true,相当于 weight 为 75。设置为 false 相当于 weight 为 50。 |
| italic | 是否倾斜 |
| underline | 是否带有下划线 |
| strikeOut | 是否带有删除线 |
代码示例: 在QtDesigner中设置字体属性
1)在界面上创建一个label

2)在右侧的属性编辑区,设置该label的font相关属性
- 在这里调整上述属性,可以实时的看到文字的变化。

3)执行程序,观察效果

代码示例: 在代码中设置字体属性
1)在界面中创建label,objectName使用默认的label即可。

2)修改widget.cpp
cpp
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置 label 的⽂本内容
ui->label->setText("这是⼀段⽂本");
// 创建字体对象
QFont font;
// 设置字体家族
font.setFamily("仿宋");
// 设置字体⼤⼩
font.setPointSize(20);
// 设置字体加粗
font.setBold(true);
// 设置字体倾斜
font.setItalic(true);
// 设置字体下划线
font.setUnderline(true);
// 设置字体删除线
font.setStrikeOut(true);
// 设置字体对象到 label 上
ui->label->setFont(font);
}
3)运行程序,观察效果


2.2.8 toolTip

- toolTip只是给用户看的.在代码中一般不需要获取到toolTip。
代码示例: 设置按钮的 toolTip
1)在界面上拖放两个按钮,objectName设置为pushButton_yes和pushButton_no

2)编写widget.cpp
cpp
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->pushButton_yes->setToolTip("这个是 yes 按钮");
ui->pushButton_yes->setToolTipDuration(3000);
ui->pushButton_no->setToolTip("这个是 no 按钮");
ui->pushButton_no->setToolTipDuration(10000);
}
3)运行程序,观察效果
可以看到鼠标停到按钮上之后,就能弹出提示,时间到后自行消失。

系统截图无法截取到鼠标光标,uu们自行尝试。
2.2.9 focusPolicy
设置控件获取到焦点的策略,比如某个控件能否用鼠标选中或者能否通过tab键选中。
- 所谓 "焦点",指的就是能选中这个元素,接下来的操作(比如键盘操作),就都是针对该焦点元素进行的了。这个对于输入框,单选框,复选框等控件非常有用的。
- 这个事情就和war3或者sc2中,先选中单位,再下达命令是一样的。


Qt::FocusPolicy 是一个枚举类型,取值如下:
| 枚举值 | 说明 |
|---|---|
| Qt::NoFocus | 控件不会接收键盘焦点 |
| Qt::TabFocus | 控件可以通过 Tab 键接收焦点 |
| Qt::ClickFocus | 控件在鼠标点击时接收焦点 |
| Qt::StrongFocus | 控件可以通过 Tab 键和鼠标点击接收焦点(默认值) |
| Qt::WheelFocus | 类似于 Qt::StrongFocus,同时控件也通过鼠标滚轮获取焦点(新增选项,一般很少使用) |
代码示例: 理解不同的 focusPolicy
1)在界面上创建四个单行输入框(LineEdit)

2)修改四个输入框的focusPolicy属性为Qt::StrongFocus(默认取值,一般不用额外修改)

此时运行程序,可以看到,使用鼠标单击 / tab,就可以移动光标所在输入框,从而接下来的输入就是针对这个获取焦点的输入框展开的了。
3)修改第二个输入框的focusPolicy为Qt::NoFocus,则第二个输入框不会被tab/鼠标左键选中

此时这个输入框也就无法输入内容了。
4)修改第二个输入框focusPolicy为Qt::TabFocus,则只能通过tab / 选中,无法通过鼠标选中。

5)修改第二个输入框focusPolicy为Qt::ClickFocus,则只能通过tab选中,无法通过鼠标选中。

2.2.10 styleSheet
通过CSS设置widget 的样式。

CSS中可以设置的样式属性非常多------基于这些属性Qt只能支持其中一部分 ,称为QSS(QtStyleSheet)。具体的支持情况可以参考Qt文档中 "Qt Style Sheets Reference"章节。
此处只是进行一个简单的演示。
代码示例: 设置文本样式
1)在界面上创建label

2)编辑右侧的styleSheet属性,设置样式

此处的语法格式同CSS,使用键值对的方式设置样式.其中键和值之间使用
:分割,键值对之间使用;分割。另外,QtDesigner只能对样式的基本格式进行校验,不能检测出哪些样式不被Qt支持.比如
text-align: center这样的文本居中操作,就无法支持。
编辑完成样式之后,可以看到在QtDesigner中能够实时预览出效果。

3)运行程序,可以看到实际效果和预览效果基本一致。
代码示例: 实现切换夜间模式。
1)在界面上创建一个多行输入框(Text Edit)和两个按钮
objectName分别为pushButton_light和pushButton_dark

2)编写按钮的 slot 函数。
- #333 是深色, 但是没那么黑;
- #fff 是纯白色;
- #000 是纯黑色。
使用在线调色板或者画图板,都可以看到数字对应的颜色,参考:在线调色板
cpp
void Widget::on_pushButton_dark_clicked()
{
this->setStyleSheet("background-color: #333");
ui->textEdit->setStyleSheet("background-color: #333; color: #fff;");
ui->pushButton_light->setStyleSheet("color: #fff");
ui->pushButton_dark->setStyleSheet("color: #fff");
}
void Widget::on_pushButton_light_clicked()
{
this->setStyleSheet("background-color: #f3f3f3");
ui->textEdit->setStyleSheet("background-color: #fff; color: #000;");
ui->pushButton_light->setStyleSheet("color: #000");
ui->pushButton_dark->setStyleSheet("color: #000");
}

3)运行程序,点击"日间模式",就是浅色背景,深色文字;点击"夜间模式",就是深色背景,浅色文字。

结尾
uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!
结语:希望对学习QT相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!
往期回顾:
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡 ૮₍ ˶ ˊ ᴥ ˋ˶₎ა
