[TOC]
🍞 Better QT
🍦 1. Qt 的一些常用技巧
1.1 快捷键
- 快捷键
Ctrl + Tab
可以切换文件; - 快捷键
Alt + ENTER
弹出代码生成提示,可以快速提示错误修改方案,类似于 IDEA 的Alt + ENTER
; - 快捷键
Alt + 鼠标
同时输入; - 快捷键
Ctrl + R
运行程序; - 快捷键
Ctrl + M
创建书签(Bookmark),或者直接在某行代码前右键添加书签; - 快捷键
Ctrl + ENTER
在当前行下方插入空行; - 快捷键
Ctrl + Shift + ENTER
在当前行下方插入空行; - 快捷键
Ctrl + I
代码对齐; - 快捷键
Ctrl + ;
格式化代码; - 快捷键
Shift + Delete
剪切当前行,可以当删除用; - 快捷键
Ctrl + Shift + R
局部变量统一修改; - 快捷键
Ctrl + Shift + V
复制历史; - 用键盘模拟鼠标操作:
功能键 方向键 备注 Ctrl Shift Alt 左/右 上/下 Home/End 方向键具有移动光标的作用 × × × 字符 字符 行首/行尾 - √ × × 单词 滚动条 文件头/尾 - √ √ × 单词 移动 行首/行尾 Shift具有选中文本的作用 √ × √ - 向上/下复制选中部分 - - - 快捷键
F1
查看帮助、文档 - 快捷键
F2
快速到变量或者函数间切换 - 快捷键
F4
快速在.cpp
文件和.h
文件间切换 - 快捷键
Ctrl + Shift + U
查找所有使用该符号的地方 - 快捷键
Ctrl + K
打开定位器 - 快捷键
Ctrl + L
跳转到某一行 - 快捷键
Ctrl + [Shift] + F
查找/替换当前文件[项目]当前选中的内容 - 快捷键
[Shift] + F3
查找下[上]一个 - 快捷键
Ctrl + B
编译工程 - 快捷键
Ctrl + R
运行工程 - 快捷键
F5
调试运行 - 快捷键
Ctrl + Shift + F5
重启调试 - 快捷键
F9
设置和取消断点 - 快捷键
F10
单步跳过 - 快捷键
F11
单步进入
1.2 Creator 片段
片段简单理解一下就是已经写好的一些模式化的代码,用户可以使用内置片段或者根据自己的需要自定义片段。
- 自带片段示例
- 自定义片段
一个用户的自定义片段需要以下几个内容:
$$片段 = 一级标题 + 二级标题 + 片段文本$$
需要通过:编辑(Edit)→首选项(Preferences)→文本编辑器(Text Editor)→片段(Snippets)进行设置
比如我要添加一个自定义片段note
,用来表示文件注释,可以选择Group
为C++
,然后选择Add
,添加指定的内容:
🍦 2. Qt 代码/文件解释
Qt的源代码和文件解释
2.1 Qt 代码
hellocosbrowser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
QT_BEGIN_NAMESPACE
namespace Ui { class HelloCOSBrowser; }
QT_END_NAMESPACE
class HelloCOSBrowser : public QWidget // QWidget 是所有应用程序窗口的基类
{
Q_OBJECT // Qt的宏, 支持 Qt 的特性, 如信号与槽、对象树、元对象等
public:
// 这里 HelloCOSBrowser 指定父窗口指针为 nullptr, 则它会作为一个独立的窗口进行展示, 否则则会作为父窗口的一个控件
// 关于这个父窗口指针, 一个很典型的应用就是 微信
// 当我们创建新窗口的时候, 如果不指定父窗口, 就会弹出一个独立的新窗口, 即电脑任务栏的图标会多出来一个
// 如果指定了父窗口, 则不会创建一个独立的窗口, 即电脑任务栏处的图标不会增加
HelloCOSBrowser(QWidget *parent = nullptr);
~HelloCOSBrowser();
private slots:
void showDialog();
private:
Ui::HelloCOSBrowser *ui;
};
2.2 Qt 工程文件解释
文件列表
文件名称 | 描述 |
---|---|
pro 文件 |
该文件是 Qt 的项目文件,qmake工具可以根据此文件生成 Makefile |
pro.user 文件 |
该文件包含和用户相关的项目信息(用户不需要关注此文件) |
ui 文件 |
Qt 的设计师界面文件 |
.cpp 文件 |
C++ 源文件 |
.h 文件 |
C++ 头文件 |
🍦 3. MOC编译器
MOC(Meta-Object Compiler)编译器
C++ 编译器本身不支持 Qt 的某些机制,Qt 希望对 C++ 代码进行自动扩展,这里就需要用到宏(例如:Q_Object
)和继承。
此外为了方便用户使用,希望用户无感知,可以将这一操作直接集成到框架中。
3.1 Qt 编译过程
1 | 预编译 -> 编译 -> 汇编 -> 链接 -> 目标 |
通过上述方式,实现 Qt 的某些特性。我们可以发现,当我们写完代码进行编译后,会产生一个 debug
文件夹,此时我们进入该文件夹,会看到一些元对象编译器编译的文件,如 moc_xxxx.cpp
或 moc_xxx.h
等文件。
3.2 MOC 的使用方法
- MOC 编译工具由 Qt 框架自动调用
- 扫描 C++ 头文件,寻找
Q_OBJECT
宏 - 生成拓展 C++ 代码,再进行预编译
- 程序员在使用时,需要继承 QObject 类或者是 QObject 子类,并且包含
Q_OBJECT
宏。
🍦 4. Qt应用程序开发
4.1 Qt Designer 设计师界面使用
① Qt 控件编辑模式
② Qt 信号与槽编辑模式
③ Qt 伙伴关系编辑模式
④ Qt Tab 顺序编辑模式:可以设置按下 Tab 键的高亮顺序
4.2 Qt 核心——信号与槽
信号与槽的基本概念
- Qt 中的信号和槽是支持多对多的,即一个信号可以对应多个槽,一个槽可以由多个信号触发。
- Qt 中的信号无需实现,可以由函数(普通函数或者槽函数)通过
emit
关键字发送信号传递参数。
4.2.1 Qt中如何定义信号
- 继承
QObject
类或其派生类,同时包含Q_OBJECT
宏 - 使用关键字
signals
声明函数信号函数,不需要具体实现信号函数 - 使用
emit
关键字发送信号
4.2.2 Qt中如何定义槽函数
- 必须包含
Q_OBJECT
宏 - 使用关键字
[public/protected/private] slots
声明函数 - 需要具体实现声明的槽函数
4.2.3 Qt中如何连接信号与槽(三种写法)
SIGNAL/SLOT
宏写法:QObject::connect(this, SIGNAL(...), this, SLOT(...));
- 函数指针写法:
QObject::connect(this, &SignalFunction, this, &SlotFunction)
- lambda 表达式写法:
QObject::connect(this, &SignalFunction, this, [=]() { qDebug() << "..."; })
三种写法的比较:
连接信号与槽 | 宏 | 函数指针 | ||||
编译 | 运行 | 编译 | 运行 | |||
参数类型 | 完全相同 | √ | √ | √ | √ | |
隐式转换 | 向上 | √ | × | √ | √ | |
向下 | √ | × | √ | √ | ||
不可以隐式转换 | √ | × | × | × | ||
参数个数 | 信号=槽 | √ | √ | √ | √ | |
信号>槽 | √ | √ | √ | √ | ||
信号<槽 | √ | × | × | × |
- 这样看来好像宏写法相对于函数指针的写法来说,可能会带来一些问题,因为有时候宏写法通过编译后,在运行阶段可能会出现一些问题;而函数指针写法可以在出现这一问题之前(编译阶段)提前发现这一问题,使得程序无法通过编译。
- 但是事实上,宏写法还是存在一定的好处,当信号函数出现重载时,使用函数指针时,无法直接进行连接(会产生报错),只能使用类型转换来进行函数指针类型的转换,如
static_cast<void QSpinBox::*)(int)>
。 - 一般情况下,推荐使用函数指针方式连接信号与槽。
- 当面对信号与槽函数有重载的情况时,推荐使用宏方式连接。
- 对于短小的槽函数的调用且功能不被复用时,推荐使用 lambda 方式连接。
4.2.4 其他连接信号与槽的方式
- 使用 Qt Designer 连接信号与槽
- 使用”转到槽”方式
- 信号与槽自动绑定
使用void on_<对象名>_<信号名>(信号参数);
时可以不使用connect
进行连接,但是当对象名、信号名或参数发生变化时,连接将会失效,且编译不会有错误提示。
4.3 Qt 窗口
4.3.1 窗口的类型
顶层窗口、次级窗口(父、子窗口)
在该图中,①可以称为顶层窗口(父窗口),②可以称为次级窗口(子窗口)。窗口中的某些按钮、输入框…等就是控件。
4.3.2 设置窗口标志
在 Qt 中可以使用 setWindowFlags()
来设置窗口标志
设置窗口无标题栏
1
this->setWindowFlags(Qt::CustomizeWindowHint);
设置窗口无边框
1
setWindowFlags(Qt::FramelessWindowHint);
设置窗口置顶
1
setWindowFlags(Qt::WindowStaysOnTopHint);
如果按照上述方式依次设置窗口标志,我们会发现当设置第 $3$ 步时前面两步的操作都失效了,这是因为设置窗口置顶时,会覆盖前面的设置。我们可以使用“或”符连接这些标志,解决这一问题:
1
setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
4.4 窗口坐标系与几何布局
4.4.1 窗口的坐标系
4.4.2 窗口的几何布局
4.5 添加图标
4.5.1 为窗口添加图标
- 准备图标文件
- 调用
setWindowIcon
方法
4.5.2 为应用程序添加图标(一般使用这种方式)
- 准备图标文件
logo.ico
- 修改 pro 工程文件
RC_ICONS = <Path>
- 通过此种方式修改图标,可执行程序
.exe
的图标会修改,且不需要额外单独设置窗口图标。
4.6 部署产品的三种方式
手动部署(不常用,比较繁琐)
进入.exe
文件所在的文件夹(debug
目录),双击运行.exe
文件,会提示缺少的文件(包括dll
动态库、plugin
插件等),然后找到对应的文件移动到.exe
文件的同级目录下即可,如下:
如果配置了环境变量则大概率不会出现报错提示缺少库的问题,那么这种方式就会失效。使用 windeployqt 部署
① 查找windeployqt.exe
程序
② 将windeployqt.exe
加入环境变量
③ 再命令行界面执行命令windeployqt.exe <exe_file_dir>
完成操作使用creator 部署
① 项目导航窗口→运行→部署→添加自定义部署
② 输入windeployqt.exe
程序及对应的命令行参数
③ 执行部署命令
🍦 5. Qt 常用控件
官方文档:Qt 6.7
一个不错的 Qt 中文文档:Qt 中文文档 5.15.1 版本
5.1 QLabel
标签控件
QLabel
的本质其实就是显示数据。其可以显示文本数据、图片数据。
了解了这些我们再来看 QLabel
的一些常用属性:
属性 | 说明 |
---|---|
text : QString |
文本内容:纯文本 |
openExternalLinks :bool |
文本内容:超链接 |
textFormat : Qt::TextFormat |
文本内容:不同类型的文本,如富文本等 |
alignment : Qt::Alignment |
文本格式:对齐方式 |
indent : int |
文本格式:缩进 |
margin : int |
文本格式:边距 |
wordWrap : bool |
文本格式:换行 |
pixmap : QPixmap |
图片内容:显示图片 |
hasSelectedText : const bool |
方法:文本是否被选中 |
scaledContents : bool |
方法:是否缩放内容 |
selectedText : const QString |
方法:获取选中的内容 |
textInteractionFlags : Qt::TextInteractionFlags |
方法:指定标签应如何与用户输入交互,若它显示文本 |
5.2 QLineEdit
单行输入框控件
QLineEdit
的本质是用于不确定的输入,如用户的手机号、用户的密码。这样就给了用户一定的自由,但是我们同时需要制定一系列的规则,以校验用户的输入。例如用户输入手机号,我们需要制定一个长度为 11
位的规则,并且输入字符中不包含字母等,以方便开发人员进行校验。当然我们也可以配合一些其他操作来优化用户体验,如:清空(如:快速清空内容)、提示(如:提示输入格式)、记忆(如:记忆之前的输入)等。
了解了这些我们可以看一下 QLineEdit
的一些常用属性(不完全,具体还是需要看文档):
属性 | 说明 |
---|---|
clearButtonEnabled : bool |
清空文本框内容 该属性保存行编辑不为空时是否显示清除按钮。 |
placeholderText : QString |
占位符文本,可以用于提示输入内容。 |
inputMask : QString |
掩码 |