Qt入门02 Qt基础数据类型和常用类 —— 大丙+Gemini
Qt入门02 Qt基础数据类型和常用类 —— 大丙+Gemini
https://www.bilibili.com/video/BV1Jp4y167R9
1. Qt基础数据类型 - #include <QtGlobal>
在日常的 C++ 编程中,我们习惯使用 int、float、double 等标准关键字。然而在跨平台开发中,标准 C++ 基础数据类型在不同操作系统或编译器下(如 32 位与 64 位系统)可能会占用不同的字节数。
由于 Qt 是一个主打跨平台的 C++ 框架,为了保证不同平台下数据类型的位宽(字节数)绝对一致,Qt 在 <QtGlobal> 头文件中专门封装并定义了一套自己的基础数据类型。
💡 核心建议:
虽然普通的业务逻辑中可以混用标准 C++ 类型,但在涉及网络通信、二进制文件读写、底层硬件交互,以及调用 Qt 官方 API 时,强烈建议使用 Qt 提供的数据类型(如
qint32、qreal),以避免跨平台移植时出现数据溢出或错乱。
以下是定义在 <QtGlobal> 中的 Qt 基本数据类型:
| 类型名 | 底层类型 (C/C++) | 说明 |
|---|---|---|
| qint8 | signed char |
8 位有符号整型 |
| qint16 | signed short |
16 位有符号整型 |
| qint32 | signed int |
32 位有符号整型 |
| qint64 | long long int 或 __int64 |
64 位有符号整型(Windows 中通常定义为 __int64) |
| qintptr | qint32 或 qint64 |
整型指针。根据操作系统不同而自动适配:32 位系统为 qint32,64 位系统为 qint64 |
| qlonglong | long long int 或 __int64 |
等同于 qint64(Windows 中定义为 __int64) |
| qptrdiff | qint32 或 qint64 |
指针差值类型。32 位系统为 qint32,64 位系统为 qint64 |
| qreal | double 或 float |
浮点数类型。默认情况下是 double(除非在编译 Qt 时配置了 -qreal float 选项,如在某些嵌入式 ARM 平台上) |
| quint8 | unsigned char |
8 位无符号整型 |
| quint16 | unsigned short |
16 位无符号整型 |
| quint32 | unsigned int |
32 位无符号整型 |
| quint64 | unsigned long long int 或 unsigned __int64 |
64 位无符号整型(Windows 中通常定义为 unsigned __int64) |
| quintptr | quint32 或 quint64 |
无符号整型指针。32 位系统为 quint32,64 位系统为 quint64 |
| qulonglong | unsigned long long int 或 unsigned __int64 |
等同于 quint64(Windows 中定义为 unsigned __int64) |
| uchar | unsigned char |
无符号字符型(Qt 对标准类型的简写) |
| uint | unsigned int |
无符号整型(Qt 对标准类型的简写) |
| ulong | unsigned long |
无符号长整型(Qt 对标准类型的简写) |
| ushort | unsigned short |
无符号短整型(Qt 对标准类型的简写) |
2. Qt中的日志输出
在 Qt 中进行日志(Log)输出时,我们一般不使用 C 语言中的 printf,也不使用 C++ 标准库中的 cout。Qt 框架提供了一套专门用于日志输出的类和全局宏,核心头文件为 <QDebug>。
2.1 在Qt Creator「应用程序输出」窗口中输出
在日常开发中,最常用的方式是将日志直接打印到 Qt Creator 底部的“应用程序输出”面板。以下是 MainWindow.cpp 中的使用示例:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QDate>
#include <QtGlobal>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 引入 <QDebug> 头文件后,直接通过全局函数 qDebug() 即可进行日志输出
// 用法与 C++ 的 cout 非常类似,支持连续的 << 操作符
qDebug() << "Date:" << QDate::currentDate();
qDebug() << "Hello!" << "I am nameless, and my id is:" << 9527;
// 除了 qDebug(),Qt 还提供了其他不同级别的日志函数:
qint8 ch = 'a';
qint32 i = 100;
qreal pi = 3.14;
qDebug() << "Debug(调试): 常规的调试信息";
qInfo() << "Info(信息): i =" << i;
qWarning() << "Warning(警告): ch =" << ch;
qCritical()<< "Critical(严重错误): pi =" << pi;
// qFatal("Fatal(致命错误): 打印后会立即让程序异常终止"); // 注意:qFatal 不支持 << 操作符
}
// ...
2.2 在控制台(Console)窗口中输出
有时候为了方便脱离 Qt Creator 独立运行程序并查看日志,或者需要查看更原生的输出流,我们可以将日志强制重定向到系统的控制台(Windows 下的 CMD 黑窗口,或 Mac/Linux 下的终端)中。
操作方法是修改项目根目录下的 *.pro 工程文件:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# 添加 console 属性,程序运行时会额外弹出一个控制台窗口用于显示输出
CONFIG += c++11 console
# ... 其他配置项
应用配置步骤:
- 修改完
.pro文件后,保存。 - 在项目名称上右键,选择 “执行 qmake”(这一步非常重要,用于重新生成 Makefile)。
- 选择 “重新构建”,然后再次编译运行。
- 程序启动时,除了主界面外,还会自动弹出一个控制台(黑窗口),所有的
qDebug()信息都会同步输出到该窗口中。
3. Qt中的字符串类型
Qt中可以使用很多种字符串类型,包括:
C语言中的char*,char[]
C++中的std::string
Qt中的QByteArray,QString
还有一些其他的操作字符串的类型,但由于使用频率不高,在此不过多介绍
QByteArray和QString是非常相似的,API基本上差不多,具体可以查询官方文档
3.1 QByteArray 核心知识点与常用 API
在 Qt 中,QByteArray 是 C 语言 char* 的面向对象升级版。在QByteArray中C语言字符串是原样封装的。QByteArray可以处理:
- 普通的文本字符串:以8位(8bit)的char位单位,
\0结尾的C字符串 - 原始二进制流数据:以1位(1bit)为单位,包含
\0的图片、音频、网络协议等数据。
3.1.1 QByteArray常用API
以下皆为部分API,其他重载的同名函数可参考Qt帮助文档, 不会也无法全部展示
1. QByteArray构造函数
//=========API===========
// 1. 构造空对象,内部无数据
QByteArray::QByteArray();
// 2. 使用data中的前size*8bit进行构造(前size个char字符)
// 2.1 size==-1,函数内部自动计算长度,计算方式: strlen(data)--->遇到'\0'的话会中断!
// 2.2 size>0,强拷贝前size个byte--->可以处理包含'\0'的二进制流
QByteArray::QByteArray(const char *data, int size = -1);
// 3. 构造一个长度为size个字节,并且每个字节值都为ch的字节数组
QByteArray::QByteArray(int size, char ch);
// 4. 拷贝构造
QByteArray::QByteArray(const QByteArray &other);
//=========示例代码===========
// 1. 构造空对象
QByteArray qbarr1;
// 2. 使用data中的size*8bit进行构造
// 2.1 缺省情况:遇 '\0' 停止
QByteArray qbarr2{"Ciallo"}; // "Ciallo"
// 2.2 指定长度:内容为前size*8bit的内容,可以处理纯二进制流 (包含 \0)
char bi_data[] = {0x01, 0x02, 0x00, 0x03, 0x04}; // 大小为5byte
// 强制拷贝 5 个字节,完整保存中间的 0x00
QByteArray qbarr3{bi_data, 5}; // "\x01\x02\x00\x03\x04"
// 3. 构造并填充重复字符
QByteArray qbarr4{3, 'A'}; // "AAA"
// 4. 拷贝构造
QByteArray qbarr5{qbarr2}; //"Ciallo"
2. 添加数据(尾部追加,头部追加,插入)
// 1. 尾部追加数据
// (其他重载的同名函数可参考Qt帮助文档, 此处略
QByteArray &QByteArray::append(const QByteArray &str);
QByteArray &QByteArray::append(const char *str);
QByteArray &QByteArray::append(const QByteArray &ba);
void QByteArray::push_back(const QByteArray &other);
// 2. 头部添加数据
// (其他重载的同名函数可参考Qt帮助文档, 此处略
QByteArray &QByteArray::prepend(const QByteArray &str);
QByteArray &QByteArray::prepend(const char *str);
QByteArray &QByteArray::prepend(const QByteArray &ba);
void QByteArray::push_front(const QByteArray &other);
// 3. 插入数据, 将 str 插入到字符串第 position 个字符的位置(从0开始)
// position处及其之后的字符都往后移
// (其他重载的同名函数可参考Qt帮助文档, 此处略
QByteArray &QByteArray::insert(int position, const QByteArray &str);
QByteArray &QByteArray::insert(int position, const char *str);
QByteArray &QByteArray::insert(int position, const QByteArray &str);
QByteArray &QByteArray::insert(int i, int count, char ch);
//========.insert示例=========
QByteArray qbarr1("nameless");
// 原本在[4]的l及后续字符都往后移
qbarr1.insert(4, " is name"); // "name is nameless"
// 在[4]的‘ ’及后续字符都往后移
qbarr1.insert(4, 3, '*'); // "name*** is nameless"
3. 删除数据(指定移除,尾删,截断,清空)
chop v/n. 砍、劈
truncate vt. 截断,截短
//========API===============
// .remove(int pos, int len)指定移除pos及其后len Byte(含pos)
QByteArray &QByteArray::remove(int pos, int len);
// .chop(int n) n 尾删n Byte
void QByteArray::chop(int n);
// .truncate(int pos) 从pos处截断删除(含pos)
void QByteArray::truncate(int pos);
// .clear() 清空数据
void QByteArray::clear();
//===========示例代码==================
// .remove(int pos, int len)指定移除pos及其后len Byte(含pos)
qba.remove(7, 3); // "0123456"
// .chop(int n) n 尾删n Byte
qba.chop(3); // "0123"
// .truncate(int pos) 从pos处截断删除(含pos)
qba.truncate(2); // "01"
// .clear() 清空数据
qba.clear(); // ""
4. 字符串替换
// .replace(before, after) 将子串 before 替换为 after
// 其他重载的同名函数可参考Qt帮助文档, 此处略
QByteArray &QByteArray::replace(const QByteArray &before, const QByteArray &after);
// 示例代码
QByteArray name{"nameless"};
QByteArray text{"Ciallo! I'm nameless!!!"};
text.replace(name, "Reimu");
// "Ciallo! I'm Reimu!!!"
5. 子串查找
//=================API============
// 判断字节数组中是否包含子字符串 ba, 包含返回true, 否则返回false
bool QByteArray::contains(const QByteArray &ba) const;
bool QByteArray::contains(const char *ba) const;
// 判断字节数组中是否包含子字符 ch, 包含返回true, 否则返回false
bool QByteArray::contains(char ch) const;
//============示例代码==============
6. 边界判断(起始边界,结尾边界)
//================API=================
// 判断字节数组是否以字符串 ba 开始, 是返回true, 不是返回false
bool QByteArray::startsWith(const QByteArray &ba) const;
bool QByteArray::startsWith(const char *ba) const;
// 判断字节数组是否以字符 ch 开始, 是返回true, 不是返回false
bool QByteArray::startsWith(char ch) const;
// 判断字节数组是否以字符串 ba 结尾, 是返回true, 不是返回false
bool QByteArray::endsWith(const QByteArray &ba) const;
bool QByteArray::endsWith(const char *ba) const;
// 判断字节数组是否以字符 ch 结尾, 是返回true, 不是返回false
bool QByteArray::endsWith(char ch) const;
//=================示例代码===========
7. 遍历(迭代器,.at(),[idx])
// 使用迭代器
iterator QByteArray::begin();
iterator QByteArray::end();
// 使用数组的方式进行遍历
// i的取值范围 0 <= i < size()
char QByteArray::at(int i) const;
char QByteArray::operator[](int i) const;
8. 返回大小(字节数)+ 返回子串/字符数量
// 返回字节数组对象中字符的个数
int QByteArray::length() const;
int QByteArray::size() const;
int QByteArray::count() const;
// 返回字节数组对象中 子字符串ba 出现的次数
int QByteArray::count(const QByteArray &ba) const;
int QByteArray::count(const char *ba) const;
// 返回字节数组对象中 字符串ch 出现的次数
int QByteArray::count(char ch) const;
9. 其他类型转换为QByteArray
// int, short, long, float, double -> QByteArray
// 其他重载的同名函数可参考Qt帮助文档, 此处略
QByteArray &QByteArray::setNum(int n, int base = 10);
QByteArray &QByteArray::setNum(short n, int base = 10);
QByteArray &QByteArray::setNum(qlonglong n, int base = 10);
QByteArray &QByteArray::setNum(float n, char f = 'g', int prec = 6);
QByteArray &QByteArray::setNum(double n, char f = 'g', int prec = 6);
[static] QByteArray QByteArray::number(int n, int base = 10);
[static] QByteArray QByteArray::number(qlonglong n, int base = 10);
[static] QByteArray QByteArray::number(double n, char f = 'g', int prec = 6);
// std::string -> QByteArray
[static] QByteArray QByteArray::fromStdString(const std::string &str);
// QByteArray -> std::string
std::string QByteArray::toStdString() const;
10. 获取C字符串 + QByteArray转换成其他类型
// 将QByteArray类型的字符串 转换为 char* 类型
char *QByteArray::data();
const char *QByteArray::data() const;
// QByteArray -> int, short, long, float, double
int QByteArray::toInt(bool *ok = Q_NULLPTR, int base = 10) const;
short QByteArray::toShort(bool *ok = Q_NULLPTR, int base = 10) const;
long QByteArray::toLong(bool *ok = Q_NULLPTR, int base = 10) const;
float QByteArray::toFloat(bool *ok = Q_NULLPTR) const;
double QByteArray::toDouble(bool *ok = Q_NULLPTR) const;
11. QArray中的全部字符大小写转换
// 所有字符转换为大写
QByteArray QByteArray::toUpper() const;
// 所有字符转换为小写
QByteArray QByteArray::toLower() const;
3.2 QString
进一步封装QByteArray
QString也是封装了字符串, 但是内部的编码为utf8, UTF-8属于Unicode字符集, 它固定使用多个字节(window为2字节, linux为3字节)来表示一个字符,这样可以将世界上几乎所有语言的常用字符收录其中。
暂时略:https://subingwen.cn/qt/qt-basetype/#3-1-QByteArray
3.3 QSstring和QByteArray的区别
暂时略
4. QVariant——Variant n. /ˈveriənt/ 变体
QVariant 可以被看作是 Qt 中最常见数据类型的“类型安全联合体”(类似于 C++17 引入的 std::variant)。在开发中,当我们面临需要传递多种不同类型的数据,或者需要在一个容器中存储异构数据(不同类型的数据)时,使用传统的结构体或单一泛型容器往往不够方便,而 QVariant 能够完美解决这个问题。
QVariant 可以保存几乎所有常见的数据类型,包括但不限于:
- Qt 核心数据类型:
QBrush、QColor、QCursor、QDateTime、QFont、QString、QByteArray、QPoint、QRect、QSize等。 - C++ 标准内置类型:
int、float、double、bool等。 - 自定义类与结构体。
4.1 QVariant 与「C++/Qt内置数据类型」的相互转换
4.1.1 将「C++/Qt内置数据类型」转换为QVariant
将内置数据类型封装进 QVariant 主要有两种方式:
-
方式一:通过构造函数直接转换
QVariant提供了大量的重载构造函数,可以在创建对象时直接传入支持的类型(如int、double、QString等)。 -
方式二:通过成员函数赋值
可以通过实例方法
.setValue()或静态方法QVariant::fromValue()来设置值,二者的内部行为完全一致。
//========API============
// 1. 通过QVariant构造函数传递参数,将支持的类型的数据设置到QVariant对象中
// 由于比较多, 大家可自行查阅Qt帮助文档, 在这里简单写几个
QVariant::QVariant(int val);
QVariant::QVariant(bool val);
QVariant::QVariant(double val);
QVariant::QVariant(const char *val);
QVariant::QVariant(const QByteArray &val);
QVariant::QVariant(const QString &val);
// 2. 通过.setValue()和QVariant::fromValue(),将支持的类型的数据设置到QVariant对象中
// 这里的 T 类型, 就是QVariant支持的类型
void QVariant::setValue(const T &value);
[static] QVariant QVariant::fromValue(const T &value);
// (两个函数内部行为完全相同,就是返回值有区别)
//============示例代码============
qint32 inum = 5;
QString qstr = "Ciallo";
// 1.使用构造函数
QVariant qv1{inum};
QVariant qv2{qstr};
// 2. 使用.setValue()和QVariant::fromValue()
QVariant qv3;
qv3.setValue(inum);
QVariant qv4 = QVariant::fromValue(qstr);
4.1.2 将QVariant转换为「C++/Qt数据类型」
从 QVariant 中提取数据分为两步:先判断类型,再进行转换。
1. 先通过.type()判断实际数据类型
// 该函数的返回值是一个枚举类型, 可通过这个枚举判断出实际是什么类型的数据
Type QVariant::type() const;
使用 .type() 方法获取当前存储数据的实际类型。该函数返回一个 QVariant::Type 枚举值。
返回值Type的部分枚举定义, 全部信息可以自行查阅Qt帮助文档
enum QMetaType::Type和enum QVariant::Type数值是一样的QMetaType::Int == QVariant::Int == 2

2. 通过.toXXX()提取实际类型的数据
// 如果要实现该操作, 可以使用QVariant类提供的 toxxx() 方法, 全部转换可以参考Qt帮助文档
// 在此举列举几个常用函数:
bool QVariant::toBool() const;
QByteArray QVariant::toByteArray() const;
double QVariant::toDouble(bool *ok = Q_NULLPTR) const;
float QVariant::toFloat(bool *ok = Q_NULLPTR) const;
int QVariant::toInt(bool *ok = Q_NULLPTR) const;
QString QVariant::toString() const;
......
3. 示例代码(MainWindow.cpp截选)
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
qint32 inum = 5;
QString qstr = "Ciallo";
QVariant qv1{inum};
QVariant qv2{qstr};
qDebug() << sum(qv1, 100).toInt();
qDebug() << sum(qv2, " nameless!").toString();
}
QVariant sum(const QVariant& a, const QVariant& b)
{
QVariant ret;
if(a.type() == QVariant::Int && b.type() == QVariant::Int)
ret.setValue(a.toInt() + b.toInt());
else if(a.type() == QVariant::String && b.type() == QVariant::String)
ret.setValue(a.toString() + b.toString());
return ret;
}
//输出:
//105
//"Ciallo nameless!"
4.2 QVariant与「自定义类型」相互转换
除了 Qt 和 C++ 的标准类型,我们自己定义的类或结构体也可以被 QVariant 封装。为了实现这一点,需要满足特定的前置条件,并且转换 API 与标准类型有所不同。
4.2.1QVariant与「自定义类型」相互转换的步骤
step1. 自定义类型的前置条件与声明
被 QVariant 存储的自定义数据类型必须具备默认构造函数和拷贝构造函数。 同时,必须在类的声明所在头文件的底部,使用 Q_DECLARE_METATYPE(自定义类名) 宏将该类型注册到 Qt 的元对象系统中。
step2. 封装自定义数据
与内置类型不同,自定义类型无法直接通过 QVariant 的构造函数进行封装,只能在 QVariant 对象构造之后,通过 .setValue() 或静态函数 QVariant::fromValue() 存入数据。
step3. 校验与提取自定义数据
自定义类型被存入后,无法使用常规的 .type() 来精确判断(对于所有自定义类型,.type() 通常只会返回 QVariant::UserType)。
提取数据需要遵循以下两步:
-
安全校验: 使用模板函数
bool QVariant::canConvert<T>()判断当前存储的数据是否能安全转换为类型T。 -
提取数据: 使用模板函数
T QVariant::value<T>()获取具体的值。
4.2.2 示例代码
// 0. 定义类型
struct Person
{
int _id;
QString _name;
};
// 1. 使用宏向 Qt 元对象系统注册自定义类型(必须放在头文件中类声明的下方)
Q_DECLARE_METATYPE(Person)
// ==========================================
// MainWindow.cpp 截选
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Person p1, p2;
p1._id = 201; p1._name = "Kuro";
p2._id = 233; p2._name = "nameless";
// 2. 封装自定义对象 (不能使用构造函数)
QVariant qv1;
qv1.setValue(p1);
QVariant qv2 = QVariant::fromValue(p2);
// 3. 校验并取出数据
if (qv1.canConvert<Person>() && qv2.canConvert<Person>())
{
Person tmp1 = qv1.value<Person>();
qDebug() << tmp1._id << ", " << tmp1._name;
Person tmp2 = qv2.value<Person>();
qDebug() << tmp2._id << ", " << tmp2._name;
}
}
// 输出:
// 201 , "Kuro"
// 233 , "nameless"
5. Qt中的坐标点、线、尺寸和矩形
在QT中我们常见的 点, 线, 尺寸, 矩形 都被进行了封装, 下边依次为大家介绍相关的类。
5.1 Qt中的坐标类:QPoint
QPoint类封装了我们常用用到的坐标点 (x, y)
5.1.1 QPoint常用API
API很多,仅截选一部分
1. QPoint构造函数
//========API===================
// 构造一个坐标原点, 即(0, 0)
QPoint::QPoint();
// 参数为 x轴坐标, y轴坐标
QPoint::QPoint(int xpos, int ypos);
2. QPoint设置x,y轴坐标
// 设置x轴坐标
void QPoint::setX(int x);
// 设置y轴坐标
void QPoint::setY(int y);
3. QPoint获取x,y轴坐标
// 得到x轴坐标
int QPoint::x() const;
// 得到x轴坐标的引用
int &QPoint::rx();
// 得到y轴坐标
int QPoint::y() const;
// 得到y轴坐标的引用
int &QPoint::ry();
4. QPoint重载的成员函数运算符
// 直接通过坐标对象进行算术运算: 加减乘除
QPoint &QPoint::operator*=(float factor);
QPoint &QPoint::operator*=(double factor);
QPoint &QPoint::operator*=(int factor);
QPoint &QPoint::operator+=(const QPoint &point);
QPoint &QPoint::operator-=(const QPoint &point);
QPoint &QPoint::operator/=(qreal divisor);
5. 重载的非成员函数友元运算符
bool
operator!=(const QPoint &p1, const QPoint &p2)
const QPoint
operator*(const QPoint &point, float factor)
const QPoint
operator*(const QPoint &point, double factor)
const QPoint
operator*(const QPoint &point, int factor)
const QPoint
operator*(float factor, const QPoint &point)
const QPoint
operator*(double factor, const QPoint &point)
const QPoint
operator*(int factor, const QPoint &point)
const QPoint
operator+(const QPoint &p1, const QPoint &p2)
5.1.2 示例代码
QPoint qp1;
QPoint qp2{150, 200};
QPoint qp3{10, 20};
qp1.setX(201);
qp1.setY(233);
qDebug() << qp1; // QPoint(201,233)
qDebug() << qp2.x() << ", " << qp2.y(); //150 , 200
qp3.rx() += 10;
qp3.ry() -= 30;
qDebug() << qp3; // QPoint(20,-10)
qp3 *= 3;
qp2 = qp2 + qp3;
qDebug() << qp2; // QPoint(210,170)
5.2 Qt中的直线类:QLine
QLine是一个直线类, 封装了两个坐标点 (两点确定一条直线)
5.2.1 QLine常用API
仅截选部分API
1. QLine构造函数
// 构造一个空对象
QLine::QLine();
// 构造一条直线, 通过两个坐标点
QLine::QLine(const QPoint &p1, const QPoint &p2);
// 从点 (x1, y1) 到 (x2, y2)
QLine::QLine(int x1, int y1, int x2, int y2);
2. 修改/设置直线两端坐标
// 给直线对象设置坐标点
void QLine::setPoints(const QPoint &p1, const QPoint &p2);
// 起始点(x1, y1), 终点(x2, y2)
void QLine::setLine(int x1, int y1, int x2, int y2);
// 设置直线的起点坐标
void QLine::setP1(const QPoint &p1);
// 设置直线的终点坐标
void QLine::setP2(const QPoint &p2);
3. 返回直线两端、中心点坐标——返回QPoint
// 返回直线的起始点坐标
QPoint QLine::p1() const;
// 返回直线的终点坐标
QPoint QLine::p2() const;
// 返回值直线的中心点坐标, (p1() + p2()) / 2
QPoint QLine::center() const;
4. 返回直线两端坐标——返回int
// 返回值直线起点的 x 坐标
int QLine::x1() const;
// 返回值直线终点的 x 坐标
int QLine::x2() const;
// 返回值直线起点的 y 坐标
int QLine::y1() const;
// 返回值直线终点的 y 坐标
int QLine::y2() const;
5. 平移直线:translate改变原直线,translated不改变原直线
// translate改变原直线
void QLine::translate(const QPoint &offset);
void QLine::translate(int dx, int dy);
// translated不改变原直线,仅返回一个平移后的直线
QLine QLine::translated(const QPoint &offset) const;
QLine QLine::translated(int dx, int dy) const;
6. 比较两个直线
// 直线对象进行比较
bool QLine::operator!=(const QLine &line) const;
bool QLine::operator==(const QLine &line) const;
5.2.2 示例代码
QLine ql1;
QLine ql2{10, 30, 100, 200};
QLine ql3{QPoint{20, 20}, QPoint{150, 150}};
ql1.setPoints(QPoint{5, 5}, QPoint{10, 10});
ql1.setLine(0, 0, 5, 5);
ql1.setP1(QPoint{1, 1});
ql1.setP2(QPoint{2, 2});
qDebug() << "ql2 p1: " << ql2.x1() << ", " << ql2.y1(); // ql2 p1: 10 , 30
qDebug() << "ql2 p2: " << ql2.x2() << ", " << ql2.y2(); // ql2 p2: 100 , 200
QPoint offset1{10, 30};
ql3.translate(offset1);
qDebug() << ql3; // QLine(QPoint(30,50),QPoint(160,180))
auto ql4 = ql3.translated(-30, -50);
qDebug() << ql3; // QLine(QPoint(30,50),QPoint(160,180))
qDebug() << ql4; // QLine(QPoint(0,0),QPoint(130,130))
qDebug() << (ql3 == ql4); // false
qDebug() << (ql3 != ql4); // true
5.3 Qt中的尺寸类:QSize
在QT中QSize类用来形容长度和宽度
5.3.1 QSize常用API
仅截选部分API
1. QSize构造函数
// 构造空对象, 对象中的宽和高都是无效的
QSize::QSize();
// 使用宽和高构造一个有效对象
QSize::QSize(int width, int height);
2. 修改/设置宽度\高度
// 设置宽度
void QSize::setWidth(int width)
// 设置高度
void QSize::setHeight(int height);
3. 获取宽度、高度及其引用
// 得到宽度
int QSize::width() const;
// 得到宽度的引用
int &QSize::rwidth();
// 得到高度
int QSize::height() const;
// 得到高度的引用
int &QSize::rheight();
4. 交换高度、宽度的值——.transpose()改变原对象;.transposed()返回改变值但原对象不变
// 交换高度和宽度的值
void QSize::transpose();
// 交换高度和宽度的值, 返回交换之后的尺寸信息
QSize QSize::transposed() const;
5. 运算符重载——单目和双目
QSize &QSize::operator*=(qreal factor);
QSize &QSize::operator+=(const QSize &size);
QSize &QSize::operator-=(const QSize &size);
QSize &QSize::operator/=(qreal divisor);
bool operator!=(const QSize &s1, const QSize &s2)
const QSize operator*(const QSize &size, qreal factor)
const QSize operator*(qreal factor, const QSize &size)
const QSize operator+(const QSize &s1, const QSize &s2)
const QSize operator-(const QSize &s1, const QSize &s2)
const QSize operator/(const QSize &size, qreal divisor)
QDataStream &operator<<(QDataStream &stream, const QSize &size)
bool operator==(const QSize &s1, const QSize &s2)
QDataStream &operator>>(QDataStream &stream, QSize &size)
5.3.2 示例代码
QSize qs1;
QSize qs2{10, 30};
qs1.setWidth(5);
qs1.setHeight(10);
qDebug() << qs1.width(); // 5
qDebug() << qs1.height(); // 10
qs2.rwidth() = 100;
qs2.rheight() = 200;
qDebug() << qs2; // QSize(100, 200)
qs1.transpose();
qDebug() << qs1; // QSize(10, 5)
auto qs3 = qs2.transposed();
qDebug() << qs2; // QSize(100, 200)
qDebug() << qs3; // QSize(200, 100)
qs2 += qs1;
qDebug() << qs2; // QSize(110, 205)
qs3 = qs2 + qs2;
qDebug() << qs3; // QSize(220, 410)
5.4 Qt中的矩形类:QRect
在Qt中使用 QRect类来描述一个矩形
5.4.1 QRect常用API
仅截取部分
1. QRect构造函数
// 构造一个空对象
QRect::QRect();
// 基于左上角坐标, 和右下角坐标构造一个矩形对象
QRect::QRect(const QPoint &topLeft, const QPoint &bottomRight);
// 通过 左上角坐标(x, y), 和 矩形尺寸(width, height) 构造一个矩形对象
QRect::QRect(const QPoint &topLeft, const QSize &size);
// 基于左上角坐标, 和 宽度, 高度构造一个矩形对象
QRect::QRect(int x, int y, int width, int height);
2. 设置/修改矩形尺寸信息
// 设置矩形的尺寸信息, 左上角坐标不变
void QRect::setSize(const QSize &size);
// 设置矩形左上角坐标为(x,y), 大小为(width, height)
void QRect::setRect(int x, int y, int width, int height);
// 设置矩形宽度
void QRect::setWidth(int width);
// 设置矩形高度
void QRect::setHeight(int height);
3. 返回矩形左上、右下、中心点坐标
// 返回值矩形左上角坐标
QPoint QRect::topLeft() const;
// 返回矩形右上角坐标
QPoint QRect::topRight() const;
// 返回矩形左下角坐标
QPoint QRect::bottomLeft() const;
// 返回矩形右下角坐标
QPoint QRect::bottomRight() const;
// 返回矩形中心点坐标
QPoint QRect::center() const;
4. 返回上、下边y轴坐标
// 返回矩形上边缘y轴坐标
int QRect::top() const;
int QRect::y() const;
// 返回值矩形下边缘y轴坐标
int QRect::bottom() const;
5. 返回左、右边x轴坐标
// 返回矩形左边缘 x轴坐标
int QRect::x() const;
int QRect::left() const;
// 返回矩形右边缘x轴坐标
int QRect::right() const;
6. 返回尺寸、宽度、高度信息
// 返回矩形的尺寸信息
QSize QRect::size() const;
// 返回矩形的宽度
int QRect::height() const;
// 返回矩形的高度
int QRect::width() const;
5.4.2 示例代码
QPoint topLeft1{30, 60}, bottomRight1{230, 360};
QPoint topLeft2{10, 15};
QSize qs2{10, 5};
QRect qr0;
QRect qr1{topLeft1, bottomRight1};
QRect qr2{topLeft2, qs2};
QRect qr3{1000, 1500, 500, 600};
qr3.setSize(QSize{1000, 1000});
qr3.setRect(2000, 3000, 10, 20);
qr3.setWidth(150);
qr3.setHeight(250);
qDebug() << qr1.topLeft(); // QPoint(30,60)
qDebug() << qr1.topRight(); // QPoint(230,60)
qDebug() << qr1.bottomLeft(); // QPoint(30,360)
qDebug() << qr1.bottomRight(); // QPoint(230,360)
6. Qt中的日期和时间类:QDate、QTime、QDateTime
6.1 日期类QDate
QDate类可以封装日期信息也可以通过这个类得到日期相关的信息, 包括:年, 月, 日。
年月日可以为负数
6.1.1 QDate常用API
1. QDate构造函数
QDate::QDate();
QDate::QDate(int y, int m, int d);
2. 设置年月日、加减年月日
// 重新设置日期对象中的日期
bool QDate::setDate(int year, int month, int day);
// 加减年月日(正负参数):返回新的QDate对象,旧QDate对象不变
// 给日期对象添加 ndays 天
QDate QDate::addDays(qint64 ndays) const;
// 给日期对象添加 nmonths 月
QDate QDate::addMonths(int nmonths) const;
// 给日期对象添加 nyears 月
QDate QDate::addYears(int nyears) const;
3. 获取对象中的年、月、日
// 1. 返回年、月、日的值
int QDate::year() const;
int QDate::month() const;
int QDate::day() const;
// 2. 传入地址/已分配内存的指针,通过指针简介获取年、月、日的值
void QDate::getDate(int *year, int *month, int *day) const;
4. 日期对象格式化(返回QString)
QString QDate::toString(const QString &format) const;
const QString &format的格式:
d - The day as a number without a leading zero (1 to 31)
dd - The day as a number with a leading zero (01 to 31)
ddd - The abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name, i.e. QLocale::system().
dddd - The long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name, i.e. QLocale::system().
M - The month as a number without a leading zero (1 to 12)
MM - The month as a number with a leading zero (01 to 12)
MMM - The abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name, i.e. QLocale::system().
MMMM - The long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name, i.e. QLocale::system().
yy - The year as a two digit number (00 to 99)
yyyy - The year as a four digit number. If the year is negative, a minus sign is prepended, making five characters.
5. 日期比较(操作符重载)
bool QDate::operator!=(const QDate &d) const;
bool QDate::operator<(const QDate &d) const;
bool QDate::operator<=(const QDate &d) const;
bool QDate::operator==(const QDate &d) const;
bool QDate::operator>(const QDate &d) const;
bool QDate::operator>=(const QDate &d) const;
6. 获取本地当前日期(静态函数)
[static] QDate QDate::currentDate();
6.1.2 示例代码
QDate qd1;
QDate qd2{2008, 8, 8};
QDate qd3{2077, 7, 7};
qd1.setDate(1999, 9, 9);
QDate qd4 = qd2.addDays(10);
QDate qd5 = qd2.addYears(-2000);
qDebug() << qd1.toString("yy-MMMM-d"); // "99-九月-9"
qDebug() << qd2.toString("yyyy-MM-dd"); // "2008-08-08"
qDebug() << qd4.toString("yy-M-d"); // "08-8-18"
qDebug() << qd5.toString("yyyy-MM-dd"); // "0008-08-08"
// 7 | 7 | 2077
qDebug() << qd3.day() << "|"
<< qd3.month() << "|"
<< qd3.year();
int a, b;
auto c = new int;
qd2.getDate(&a, &b, c);
// 8 | 8 | 2008
qDebug() << *c << "|" << b << "|" << a;
qDebug() << (qd1 == QDate{1999, 9, 9}); // true
qDebug() << (qd1 >= qd3); // false
// "26-05-20"
qDebug() << QDate::currentDate().toString("yy-MM-dd");
6.2 时间类QTime
QTime类可以封装时间信息也可以通过这个类得到时间相关的信息, 包括:时, 分, 秒, 毫秒。
6.2.1 QTime常用API
1. QTime构造函数
QTime::QTime();
QTime::QTime(int h, int m, int s = 0, int ms = 0);
/*
h ==> 取值范围: 0 ~ 23
m and s ==> 取值范围: 0 ~ 59
ms ==> 取值范围: 0 ~ 999
*/
示例代码:
// ========== 1. 构造函数 ==========
QTime qt1; // 默认构造,无效时间
qDebug() << qt1.isValid(); // false
QTime qt2{14, 0, 0}; // 14:00:00
QTime qt3(9, 30, 15, 500); // 09:30:15.500
QTime qt4{25, 0, 0}; // 无效时间,超出范围
qDebug() << "t4 valid: " << qt4.isValid(); // t4 valid: false
2. 设置/重设时间 .setHMS()
// Returns true if the set time is valid; otherwise returns false.
bool QTime::setHMS(int h, int m, int s, int ms = 0);
示例代码:
// ========== 2. 设置时间.setHMS() ==========
QTime qt5;
bool success = qt5.setHMS(23, 59, 59, 999);
qDebug() << "设置成功:" << success;
qDebug() << qt5.toString("hh:mm:ss.zzz"); // "23:59:59.999"
success = qt5.setHMS(24, 0, 0); // 小时超出范围
qDebug() << "success: " << success; // false
3. 加减时间
- 参数为正:增加时间
- 参数为负:减去时间
QTime QTime::addSecs(int s) const;
QTime QTime::addMSecs(int ms) const;
示例代码:
// ========== 3. addSecs 和 addMSecs ==========
qDebug() << "\n========== 时间加减 ==========";
QTime n(14, 0, 0); // n == 14:00:00
QTime t;
t = n.addSecs(70); // t == 14:01:10
qDebug() << "n + 70s:" << t.toString("hh:mm:ss");
t = n.addSecs(-70); // t == 13:58:50
qDebug() << "n - 70s:" << t.toString("hh:mm:ss");
t = n.addSecs(10 * 60 * 60 + 5); // t == 00:00:05 (跨天)
qDebug() << "n + 10h5s:" << t.toString("hh:mm:ss");
t = n.addSecs(-15 * 60 * 60); // t == 23:00:00 (跨天)
qDebug() << "n - 15h:" << t.toString("hh:mm:ss");
t = n.addMSecs(1500); // 加1.5秒
qDebug() << "n + 1500ms:" << t.toString("hh:mm:ss.zzz");
4. 从对象中获取时、分、秒、毫秒的值
// Returns the hour part (0 to 23) of the time. Returns -1 if the time is invalid.
int QTime::hour() const;
// Returns the minute part (0 to 59) of the time. Returns -1 if the time is invalid.
int QTime::minute() const;
// Returns the second part (0 to 59) of the time. Returns -1 if the time is invalid.
int QTime::second() const;
// Returns the millisecond part (0 to 999) of the time. Returns -1 if the time is invalid.
int QTime::msec() const;
5. 获取时间字符串(格式化)
QString QTime::toString(const QString &format) const;
-- 时 --
h ==> The hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
hh ==> The hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
H ==> The hour without a leading zero (0 to 23, even with AM/PM display)
HH ==> The hour with a leading zero (00 to 23, even with AM/PM display)
-- 分 --
m ==> The minute without a leading zero (0 to 59)
mm ==> The minute with a leading zero (00 to 59)
-- 秒 --
s ==> The whole second, without any leading zero (0 to 59)
ss ==> The whole second, with a leading zero where applicable (00 to 59)
-- 毫秒 --
zzz ==> The fractional part of the second, to millisecond precision,
including trailing zeroes where applicable (000 to 999).
-- 上午或者下午
AP or A ==> 使用AM/PM(大写) 描述上下午, 中文系统显示汉字
ap or a ==> 使用am/pm(小写) 描述上下午, 中文系统显示汉字
6. 阶段性计时
// 过时的API函数
// 开始计时
void QTime::start();
// 计时结束
int QTime::elapsed() const;
// 重新计时
int QTime::restart();
// 推荐使用的API函数
// QElapsedTimer 类
void QElapsedTimer::start();
qint64 QElapsedTimer::restart();
qint64 QElapsedTimer::elapsed() const;
7. 时间比较(操作符重载)
bool QTime::operator!=(const QTime &t) const;
bool QTime::operator<(const QTime &t) const;
bool QTime::operator<=(const QTime &t) const;
bool QTime::operator==(const QTime &t) const;
bool QTime::operator>(const QTime &t) const;
bool QTime::operator>=(const QTime &t) const;
8. 获取当前系统时间(静态函数)
[static] QTime QTime::currentTime();
6.3 日期时间类QDateTime
QDateTime类可以封装日期和时间信息也可以通过这个类得到日期和时间相关的信息, 包括:年, 月, 日, 时, 分, 秒, 毫秒。其实这个类就是QDate 和 QTime 这两个类的结合体。
可以存储日期+时间,也可以仅存储日期,或仅存储时间。
6.3.1 常用API
// 构造函数
QDateTime::QDateTime();
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec = Qt::LocalTime);
// 公共成员函数
// 设置日期
void QDateTime::setDate(const QDate &date);
// 设置时间
void QDateTime::setTime(const QTime &time);
// 给当前日期对象追加 年/月/日/秒/毫秒, 参数可以是负数
QDateTime QDateTime::addYears(int nyears) const;
QDateTime QDateTime::addMonths(int nmonths) const;
QDateTime QDateTime::addDays(qint64 ndays) const;
QDateTime QDateTime::addSecs(qint64 s) const;
QDateTime QDateTime::addMSecs(qint64 msecs) const;
// 得到对象中的日期
QDate QDateTime::date() const;
// 得到对象中的时间
QTime QDateTime::time() const;
// 日期和时间格式, 格式字符参考QDate 和 QTime 类的 toString() 函数
QString QDateTime::toString(const QString &format) const;
// 操作符重载 ==> 日期时间对象的比较
bool QDateTime::operator!=(const QDateTime &other) const;
bool QDateTime::operator<(const QDateTime &other) const;
bool QDateTime::operator<=(const QDateTime &other) const;
bool QDateTime::operator==(const QDateTime &other) const;
bool QDateTime::operator>(const QDateTime &other) const;
bool QDateTime::operator>=(const QDateTime &other) const;
// 静态函数
// 得到当前时区的日期和时间(本地设置的时区对应的日期和时间)
[static] QDateTime QDateTime::currentDateTime();

浙公网安备 33010602011771号