# 1. 基础类型

因为Qt是一个C++框架, 因此C++中所有的语法和数据类型在Qt中都是被支持的, 但是Qt中也定义了一些属于自己的数据类型, 下边给大家介绍一下这些基础的数类型。

QT基本数据类型定义在`#include <QtGlobal>` 中，QT基本数据类型有：

| 类型名称   | 注释                                         | 备注                                                         |
| ---------- | -------------------------------------------- | ------------------------------------------------------------ |
| qint8      | signed char                                  | 有符号8位数据                                                |
| qint16     | signed short                                 | 16位数据类型                                                 |
| qint32     | signed short                                 | 32位有符号数据类型                                           |
| qint64     | long long int 或(__int64)                    | 64位有符号数据类型，Windows中定义为__int64                   |
| qintptr    | qint32 或 qint64                             | 指针类型 根据系统类型不同而不同，32位系统为qint32、64位系统为qint64 |
| qlonglong  | long long int 或(__int64)                    | Windows中定义为__int64                                       |
| qptrdiff   | qint32 或 qint64                             | 根据系统类型不同而不同，32位系统为qint32、64位系统为qint64   |
| qreal      | double 或 float                              | 除非配置了-qreal float选项，否则默认为double                 |
| 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) | Windows中定义为__int64                                       |
| uchar      | unsigned char                                | 无符号字符类型                                               |
| uint       | unsigned int                                 | 无符号整型                                                   |
| ulong      | unsigned long                                | 无符号长整型                                                 |
| ushort     | unsigned short                               | 无符号短整型                                                 |
| qsizetype  | size_t                                       |                                                              |



# 2. log输出

> 在Qt中进行log输出, 一般不使用c中的`printf`, 也不是使用C++中的`cout`, Qt框架提供了专门用于日志输出的类, 头文件名为 `QDebug`。

**基本分类**

+ qDebug：调试信息提示
+ qInfo     ：输出信息
+ qWarning ：一般的警告提示
+ qCritical ：严重的错误提示
+ qFatal ：致命错误提示，会直接中断程序

**C风格输出**

```cpp
qDebug("我是%s，今年%d岁了~","maye",20);
qInfo("maye%d",666);
qWarning("hello %s","warning");
qCritical("helo %s","critical");
qFatal("hello %s","qFatal");		//致命错误会直接中断程序
```

**C++风格**

```cpp
qDebug()<<"好帅"<<endl;
qInfo()<<"qInfo"<<endl;
qWarning()<<"qWarnning"<<endl;
qCritical()<<"qCritical"<<endl;
#qFatal()<<"qFatal"<<endl;			//致命错误不能用<<输出
```

可以抑制输出

```cpp
#define QT_NO_DEBUG_OUTPUT	//抑制qDebug输出
#define QT_NO_INFO_OUTPUT	//抑制qInfo输出
...
```





# 3. 字符串类型

> C     => `char*`
>
> C++ => `std::string`
>
> Qt	=> `QByteArray`, `QString`

## 3.1 QByteArray

> 在Qt中`QByteArray`可以看做是C语言中 `char*`的升级版本。我们在使用这种类型的时候可通过这个类的构造函数申请一块动态内存，用于存储我们需要处理的字符串数据。
>
> 下面给大家介绍一下这个类中常用的一些API函数，`大家要养成遇到问题主动查询帮助文档的好习惯`

- 构造函数

  ```c++
  // 构造空对象, 里边没有数据
  QByteArray::QByteArray();
  // 将data中的size个字符进行构造, 得到一个字节数组对象
  // 如果 size==-1 函数内部自动计算字符串长度, 计算方式为: strlen(data)
  QByteArray::QByteArray(const char *data, int size = -1);
  // 构造一个长度为size个字节, 并且每个字节值都为ch的字节数组
  QByteArray::QByteArray(int size, char ch);
  ```

  

- 数据操作

  ```c++
  // 其他重载的同名函数可参考Qt帮助文档, 此处略
  QByteArray &QByteArray::append(const QByteArray &ba);
  void QByteArray::push_back(const QByteArray &other);
  
  // 其他重载的同名函数可参考Qt帮助文档, 此处略
  QByteArray &QByteArray::prepend(const QByteArray &ba);
  void QByteArray::push_front(const QByteArray &other);
  
  // 插入数据, 将ba插入到数组第 i 个字节的位置(从0开始)
  // 其他重载的同名函数可参考Qt帮助文档, 此处略
  QByteArray &QByteArray::insert(int i, const QByteArray &ba);
  
  // 删除数据
  // 从大字符串中删除len个字符, 从第pos个字符的位置开始删除
  QByteArray &QByteArray::remove(int pos, int len);
  // 从字符数组的尾部删除 n 个字节
  void QByteArray::chop(int n);
  // 从字节数组的 pos 位置将数组截断 (前边部分留下, 后边部分被删除)
  void QByteArray::truncate(int pos);
  // 将对象中的数据清空, 使其为null
  void QByteArray::clear();
  
  // 字符串替换
  // 将字节数组中的 子字符串 before 替换为 after
  // 其他重载的同名函数可参考Qt帮助文档, 此处略
  QByteArray &QByteArray::replace(const QByteArray &before, const QByteArray &after);
  ```
  
- 子字符串查找和判断

  ```c++
  // 判断字节数组中是否包含子字符串 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;
  
  // 判断字节数组是否以字符串 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;
  ```

  

- 遍历

  ```c++
  // 使用迭代器
  iterator QByteArray::begin();
  iterator QByteArray::end();
  
  // 使用数组的方式进行遍历
  // i的取值范围 0 <= i < size()
  char QByteArray::at(int i) const;
  char QByteArray::operator[](int i) const;
  
  ```

  

- 查看字节数

  ```c++
  // 返回字节数组对象中字符的个数
  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;
  ```

- 类型转换

  ```c++
  // 将QByteArray类型的字符串 转换为 char* 类型
  char *QByteArray::data();
  const char *QByteArray::data() const;
  
  // 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);
  
  // 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;
  
  // std::string -> QByteArray
  [static] QByteArray QByteArray::fromStdString(const std::string &str);
  // QByteArray -> std::string
  std::string QByteArray::toStdString() const;
  
  // 所有字符转换为大写
  QByteArray QByteArray::toUpper() const;
  // 所有字符转换为小写
  QByteArray QByteArray::toLower() const;
  ```

  

## 3.2 QString

> QString也是封装了字符串, 但是内部的编码为`utf8`, UTF-8属于Unicode字符集, 它固定使用多个字节（window为2字节, linux为3字节）来表示一个字符，这样可以将世界上几乎所有语言的常用字符收录其中。
>
> 下面给大家介绍一下这个类中常用的一些API函数。

### 构造函数

```c++
// 构造一个空字符串对象
QString();
// 将 char* 字符串 转换为 QString 类型
QString(const char *str);
// 将 QByteArray 转换为 QString 类型
QString(const QByteArray &ba);
// 其他重载的同名构造函数可参考Qt帮助文档, 此处略
```



### 数据操作

```c++
// 尾部追加数据
QString& append(const QString &str);
QString& append(const char *str);
QString& append(const QByteArray &ba);
void push_back(const QString &other);

// 头部添加数据
QString& prepend(const QString &str);
QString& prepend(const char *str);
QString& prepend(const QByteArray &ba);
void QString::push_front(const QString &other);

// 插入数据, 将 str 插入到字符串第 position 个字符的位置(从0开始)
QString& insert(int position, const QString &str);
QString& insert(int position, const char *str);
QString& insert(int position, const QByteArray &str);

// 删除数据
// 从大字符串中删除len个字符, 从第pos个字符的位置开始删除
QString& remove(int position, int n);

// 从字符串的尾部删除 n 个字符
void  chop(int n);
// 从字节串的 position 位置将字符串截断 (前边部分留下, 后边部分被删除)
void  truncate(int position);
// 将对象中的数据清空, 使其为null
void  clear();

// 字符串替换
// 将字节数组中的 子字符串 before 替换为 after
// 参数 cs 为是否区分大小写, 默认区分大小写
QString& replace(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
```

### 子字符串查找和判断

```c++
// 参数 cs 为是否区分大小写, 默认区分大小写
// 其他重载的同名函数可参考Qt帮助文档, 此处略

// 判断字符串中是否包含子字符串 str, 包含返回true, 否则返回false
bool  contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

// 判断字符串是否以字符串 ba 开始, 是返回true, 不是返回false
bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

// 判断字符串是否以字符串 ba 结尾, 是返回true, 不是返回false
bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
```

### 遍历

```c++
// 使用迭代器
iterator  begin();
iterator  end();

// 使用数组的方式进行遍历
const QChar  at(int position) const
const QChar  operator[](int position) const;
```

### 查看字节数

```c++
// 返回字节数组对象中字符的个数
int  length() const;
int  size() const;
int  count() const;

// 返回字节串对象中 子字符串 str 出现的次数
// 参数 cs 为是否区分大小写, 默认区分大小写
int  count(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
```

### 类型转换

```c++
// int, short, long, float, double -> QString
// 其他重载的同名函数可参考Qt帮助文档, 此处略
QString& setNum(int n, int base = 10);
QString& setNum(short n, int base = 10);
QString& setNum(long n, int base = 10);
QString& setNum(float n, char format = 'g', int precision = 6);
QString& QString::setNum(double n, char format = 'g', int precision = 6);
[static] QString QString::number(long n, int base = 10);
[static] QString QString::number(int n, int base = 10);
[static] QString QString::number(double n, char format = 'g', int precision = 6);

// QString -> int, short, long, float, double
int QString::toInt(bool *ok = Q_NULLPTR, int base = 10) const;
short QString::toShort(bool *ok = Q_NULLPTR, int base = 10) const;
long QString::toLong(bool *ok = Q_NULLPTR, int base = 10) const
float QString::toFloat(bool *ok = Q_NULLPTR) const;
double QString::toDouble(bool *ok = Q_NULLPTR) const;


// 所有字符转换为大写
QString QString::toUpper() const;
// 所有字符转换为小写
QString QString::toLower() const;
```

### 字符串格式化

C语言中有sprintf()函数，QString也提供了一个asprintf()函数。

```cpp
 QString res =  asprintf("fileName:%s size:%d","./av.jpg",20);
 qDebug()<<res<<endl;
```

不过QString还提供的另一种格式化字符串输出的函数arg()，更为方便。

```c++
QString arg(const QString &a, int fieldWidth = 0, QChar fillChar = QLatin1Char( ' ' )) const;
QString arg(int a, int fieldWidth = 0, int base = 10, QChar fillChar = QLatin1Char( ' ' )) const;
//用于填充字符串中的%1,%2…为给定格式的整形数字，其中第一个参数是要填充的数字，第二个参数为最小宽度，第三个参数为进制，第四个参数为当原始数字长度不足最小宽度时用于填充的字符

// 示例程序
QString str =  QString("%1 %2 %3").arg(1).arg(2);
str = str.arg("hello");
qDebug()<<str<<endl;     //"hello 2 1"

QString text = QString("%1:%2:%3").arg(1,2,10,QChar('0')).arg(35).arg(59);
qDebug()<<text<<endl;    //"01:35:59"
```

## 3.2 不同字符串类型相互转换

```cpp
// std::string -> QString
[static] QString QString::fromStdString(const std::string &str);
// QString -> std::string
std::string QString::toStdString() const;

#QString -> QByteArray
// 转换为本地编码, 跟随操作系统
QByteArray QString::toLocal8Bit() const;
// 转换为 Latin-1 编码的字符串 不支持中文
QByteArray QString::toLatin1() const;
// 转换为 utf8 编码格式的字符串 (常用)
QByteArray QString::toUtf8() const;

#QByteArray -> QString
//使用QString的构造函数即可
```





# 4. QVariant

> QVariant(变体数据类型)这个类很神奇，或者说方便。很多时候，需要几种不同的数据类型需要传递，如果用结构体，又不大方便，容器保存的也只是一种数据类型，而QVariant则可以统统搞定。
>
> QVariant 这个类型充当着最常见的数据类型的联合。QVariant 可以保存很多Qt的数据类型，包括`QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、QRegion、QSize和QString`，并且还有C++基本类型，如` int、float`等。

## 4.1 标准类型

- 将标准类型转换为QVariant类型

```c++
// 这类转换需要使用QVariant类的构造函数, 由于比较多, 大家可自行查阅Qt帮助文档, 在这里简单写几个
QVariant(int val);
QVariant(bool val);
QVariant(double val);
QVariant(const char *val);
QVariant(const QByteArray &val);
QVariant(const QString &val);
......
    
// 使用设置函数也可以将支持的类型的数据设置到QVariant对象中
// 这里的 T 类型, 就是QVariant支持的类型
void setValue(const T &value);
// 该函数行为和 setValue() 函数完全相同
[static] QVariant fromValue(const T &value);
```

**Exmple**

```cpp
QVariant v(5);

QVariant v;
v.setValue(5);

QVariant v = QVariant::fromValue(5);

int i = v.toInt();          // i is now 5
QString s = v.toString();   // s is now "5"
```

- 判断 QVariant中封装的实际数据类型

> Type 是枚举类型

```c++
//获取类型名
const char *typeName() const;
//根据类型id(枚举)获取类型名(字符串)
[static] const char *typeToName(int typeId);
//根据类型名(字符串)获取类型id(枚举)
[static] Type nameToType(const char *name);
```



- 将QVariant对象转换为实际的数据类型

```c++
//在转换之前可以先判断能够转换成对应的类型
bool canConvert(int targetTypeId) const
bool canConvert() const

bool 		toBool() const;
QByteArray 	toByteArray() const;
double 		toDouble(bool *ok = Q_NULLPTR) const;
float 		toFloat(bool *ok = Q_NULLPTR) const;
int 		toInt(bool *ok = Q_NULLPTR) const;
QString 	toString() const;
......

T value() const
//v.value<int>();       
```



## 4.2 自定义类型

> 除了标准类型, 我们自定义的类型也可以使用`QVariant`类进行封装, `被QVariant存储的数据类型需要有一个默认的构造函数和一个拷贝构造函数`。为了实现这个功能，首先必须使用`Q_DECLARE_METATYPE()`宏。通常会将这个宏放在类的声明所在头文件的下面， 原型为： 
>
> `Q_DECLARE_METATYPE(Type)`
>
> 使用的具体步骤如下: 

- 第一步: 定义类型，并注册

  ```c++
  //自定义类型
  class Animal
  {
  public:
      Animal(){}  //必须要有默认构造函数
                  //拷贝构造函数也必须有，不过没有深、浅拷贝时，用默认的即可
      Animal(QString name):_name(name){}
      void show()
      {
          qDebug()<<"Animal show name is :"<< _name <<endl;
      }
  private:
      QString _name;
  };
  //自定义类型注册 Qt6后无须注册了
  Q_DECLARE_METATYPE(Animal);
  ```

- 第二步: 使用forvalue()存储对象

  ```c++
  int main()
  {
      //QVariant vt(Animal("snake"));	//不可以通过构造函数存自定义类型
      QVariant vt;
      //有以下两种方法可以，存自定义类型
      vt = QVariant::fromValue(Animal("dog"));	//①
      vt.setValue(Animal("cat"));					//②
      //如果能转换到Animal类型，就转换
      if(vt.canConvert<Animal>())
      {
          Animal animal = vt.value<Animal>();
          animal.show();
      }
  	return 0;
  }
  ```

操作涉及的API如下:

```c++
// 如果当前QVariant对象可用转换为对应的模板类型 T, 返回true, 否则返回false
bool canConvert() const;
// 将当前QVariant对象转换为实际的 T 类型
T value() const;
```





# 5. 位置和尺寸

> 在QT中我们常见的 点, 线, 尺寸, 矩形 都被进行了封装, 下边依次为大家介绍相关的类。

## 5.1 QPoint

> `QPoint`类封装了我们常用用到的坐标点 (x, y), 常用的 API如下:

```c++
void QPoint::setX(int x);
void QPoint::setY(int y);

int QPoint::x() const;
int &QPoint::rx();

int QPoint::y() const;
int &QPoint::ry();

//如果x和y坐标都为0则返回true，否则返回false
bool isNull() const

//返回x()和y()的绝对值之和，传统上称为从原点到该点的向量的“曼哈顿长度”。
//(p1-p2).manhattanLength();   
int manhattanLength() const    

//返回一个交换了x和y坐标的点:   QPoint{1, 2}.transposed() // {2, 1}  
QPoint transposed() const    
    
// 直接通过坐标对象进行算术运算: 加减乘除
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.2 QLine

> `QLine`是一个直线类, 封装了两个坐标点 (`两点确定一条直线`)
>
> 常用API如下:

```c++
// 设置直线的起点坐标
void setP1(const QPoint &p1);
// 设置直线的终点坐标
void setP2(const QPoint &p2);

void setPoints(const QPoint &p1, const QPoint &p2);
void setLine(int x1, int y1, int x2, int y2);


QPoint p1() const;		// 返回直线的起始点坐标
QPoint p2() const;		// 返回直线的终点坐标
QPoint center() const;	// 返回值直线的中心点坐标, (p1() + p2()) / 2	


int x1() const;		// 返回值直线起点的 x 坐标
int y1() const;		// 返回值直线起点的 y 坐标
int x2() const;		// 返回值直线终点的 x 坐标
int y2() const;		// 返回值直线终点的 y 坐标

int dx() const			//返回直线向量的水平分量  
int dy() const			//返回直线向量的垂直分量  

// 用给定的坐标点平移这条直线
void translate(const QPoint &offset);
void translate(int dx, int dy);
// 用给定的坐标点平移这条直线, 返回平移之后的坐标点(不会改变这条线的坐标)
QLine translated(const QPoint &offset) const;
QLine translated(int dx, int dy) const;

// 直线对象进行比较
bool operator!=(const QLine &line) const;
bool operator==(const QLine &line) const;
```



## 5.3 QSize

> 在QT中`QSize`类用来形容长度和宽度, 常用的API如下:

```c++
void setWidth(int width)
void setHeight(int height);

int width() const;		// 得到宽度
int &rwidth();			// 得到宽度的引用
int height() const;		// 得到高度
int &rheight();			// 得到高度的引用

void transpose();			// 交换高度和宽度的值
QSize transposed() const;	// 交换高度和宽度的值, 返回交换之后的尺寸信息

//返回一个大小，宽为当前大小与other的最小值，高为当前大小与other的最小值
QSize boundedTo(const QSize& oterSize)
//返回一个大小，宽为当前大小与other的最大值，高为当前大小与other的最大值    
QSize expandedTo(const QSize &otherSize) const    
    
/*
根据指定的模式，按给定的宽度和高度缩放矩形:  
	如果mode为Qt::IgnoreAspectRatio，则大小设置为(width, height)。  
	如果mode为Qt::KeepAspectRatio，当前大小将在内部缩放到一个尽可能大的矩形(宽度，高度)，保持高宽比。  
	如果mode是Qt::KeepAspectRatioByExpanding，当前大小被缩放到一个矩形，尽可能小的外部(宽度，高度)，保持长宽比。  
*/
void scale(int width, int height, Qt::AspectRatioMode mode)
void scale(const QSize &size, Qt::AspectRatioMode mode)
QSize scaled(int width, int height, Qt::AspectRatioMode mode) const
QSize scaled(const QSize &s, Qt::AspectRatioMode mode) const
    

// 进行算法运算: 加减乘除
QSize &operator*=(qreal factor);
QSize &operator+=(const QSize &size);
QSize &operator-=(const QSize &size);
QSize &operator/=(qreal divisor);
```



## 5.4 QRect

> 在Qt中使用 `QRect`类来描述一个矩形, 常用的API如下:

```c++
// 构造一个空对象
QRect::QRect();
// 基于左上角坐标, 和右下角坐标构造一个矩形对象
QRect::QRect(const QPoint &topLeft, const QPoint &bottomRight);
// 基于左上角坐标, 和 宽度, 高度构造一个矩形对象
QRect::QRect(const QPoint &topLeft, const QSize &size);
// 通过 左上角坐标(x, y), 和 矩形尺寸(width, height) 构造一个矩形对象
QRect::QRect(int x, int y, int width, int height);

// 设置矩形的尺寸信息, 左上角坐标不变
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);

// 返回值矩形左上角坐标
QPoint QRect::topLeft() const;
// 返回矩形右上角坐标
// 该坐标点值为: QPoint(left() + width() -1, top())
QPoint QRect::topRight() const;
// 返回矩形左下角坐标
// 该坐标点值为: QPoint(left(), top() + height() - 1)
QPoint QRect::bottomLeft() const;
// 返回矩形右下角坐标
// 该坐标点值为: QPoint(left() + width() -1, top() + height() - 1)
QPoint QRect::bottomRight() const;
// 返回矩形中心点坐标
QPoint QRect::center() const;

// 返回矩形上边缘y轴坐标
int QRect::top() const;
int QRect::y() const;
// 返回值矩形下边缘y轴坐标
int QRect::bottom() const;
// 返回矩形左边缘 x轴坐标
int QRect::x() const;
int QRect::left() const;
// 返回矩形右边缘x轴坐标
int QRect::right() const;

// 返回矩形的高度
int QRect::width() const;
// 返回矩形的宽度
int QRect::height() const;
// 返回矩形的尺寸信息
QSize QRect::size() const;

//调整矩形的尺寸 （左上角和右下角坐标偏移量）
void QRect::adjust(int dx1, int dy1, int dx2, int dy2)
QRect QRect::adjusted(int dx1, int dy1, int dx2, int dy2) const    
```

QPoint，QLine，QSize，QRect各自都还有浮点型版本的，分别是QPointF，QLineF，QSizeF，QRectF，函数基本一样

# 6. 日期和时间

## 6.1. QDate

```c++
// 构造函数
QDate::QDate();
QDate::QDate(int y, int m, int d);

// 公共成员函数
// 重新设置日期对象中的日期
bool QDate::setDate(int year, int month, int day);
// 给日期对象添加 ndays 天
QDate QDate::addDays(qint64 ndays) const;
// 给日期对象添加 nmonths 月
QDate QDate::addMonths(int nmonths) const;
// 给日期对象添加 nyears 月
QDate QDate::addYears(int nyears) const;

// 得到日期对象中的年/月/日
int QDate::year() const;
int QDate::month() const;
int QDate::day() const;
void QDate::getDate(int *year, int *month, int *day) const;
 
/*日期对象格式化
    d 		- 	没有前导零的日子 (1 to 31)  
    dd		-	前导为0的日子   (01 to 31)  
    ddd		-	显示(缩写) 周一、周二、周三、周四、周五、周六、周日		
    dddd	- 	显示(完整) 星期一、星期二、星期三、星期四、星期五、星期六、星期日
    
    M		-	没有前导零的月份(1到12)  
    MM		-	前导零的月份(01到12)  
    MMM		-	缩写 1月、2月、3月...         
    MMMM	-	完整 一月、二月、三月...
    
    yy		-	两个数字的年 (00 to 99)
    yyyy	-	以四位数表示的年份
*/
QString QDate::toString(const QString &format) 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;
bool QDate::operator>=(const QDate &d) const;

// 静态函数 -> 得到本地的当前日期
[static] QDate QDate::currentDate();
```



## 6.2. QTime

```c++
// 构造函数
QTime::QTime();
/*
    h 			==> must be in the range 0 to 23
    m and s 	==> must be in the range 0 to 59
    ms 			==> must be in the range 0 to 999
*/ 
QTime::QTime(int h, int m, int s = 0, int ms = 0);

// 公共成员函数
// Returns true if the set time is valid; otherwise returns false.
bool QTime::setHMS(int h, int m, int s, int ms = 0);
QTime QTime::addSecs(int s) const;
QTime QTime::addMSecs(int ms) const;

// 示例代码
  QTime n(14, 0, 0);                // n == 14:00:00
  QTime t;
  t = n.addSecs(70);                // t == 14:01:10
  t = n.addSecs(-70);               // t == 13:58:50
  t = n.addSecs(10 * 60 * 60 + 5);  // t == 00:00:05
  t = n.addSecs(-15 * 60 * 60);     // t == 23:00:00

// 从时间对象中取出 时/分/秒/毫秒
// 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;


// 时间格式化
/*
	-- 时
    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(小写) 描述上下午, 中文系统显示汉字
*/
QString QTime::toString(const QString &format) 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;
bool QTime::operator>=(const QTime &t) const;

// 静态函数 -> 得到当前时间
[static] QTime QTime::currentTime();
```



### 经时计时器

QTime的经时计时器已经过时了，推荐使用QElapsedTimer。

```cpp
// 推荐使用的API函数
// QElapsedTimer 类
void QElapsedTimer::start();
qint64 QElapsedTimer::restart();
qint64 QElapsedTimer::elapsed() const;
```

+ 主要的使用方法就是测量一个操作耗时多久，例子如下：

  ```cpp
  QElapsedTimer elapse;
  elapse.start();
  
  for(int i = 0;i<10000000;i++);
  
  qDebug()<<elapse.elapsed()<<endl;
  ```

  



## 6.3. QDateTime

```c++
// 构造函数
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();
```



# 7，Container

## 介绍

Qt库提供了一组通用的基于模板的容器类。这些类可用于存储指定类型的项。例如，如果您需要一个可调整大小的QString数组，请使用QList<QString>。

这些容器类被设计成比STL容器更轻、更安全、更容易使用。如果您不熟悉STL，或者更喜欢使用“Qt方式”，您可以使用这些类而不是STL类。

容器类是隐式共享的，它们是可重入的，并且它们被优化为速度、低内存消耗和最小的内联代码扩展，从而导致更小的可执行文件。此外，在所有用于访问它们的线程将它们用作只读容器的情况下，它们是线程安全的。

容器提供了遍历的迭代器。STL风格的迭代器是最有效的迭代器，可以与Qt和STL的泛型算法一起使用。提供java风格的迭代器是为了向后兼容。

## 容器类

Qt提供了以下顺序容器:QList、QStack和QQueue。 对于大多数应用程序，QList是最好的类型。 它提供了非常快的追加。 如果您确实需要一个链表，请使用std::list。 QStack和QQueue是提供LIFO和FIFO语义的方便类。

Qt还提供了这些关联容器:QMap、QMultiMap、QHash、QMultiHash和QSet。 “Multi”容器方便地支持与单个键关联的多个值。 “哈希”容器通过使用哈希函数而不是对排序集进行二进制搜索来提供更快的查找。

 作为特殊情况，QCache和QContiguousCache类在有限的缓存存储中提供对象的高效哈希查找。

| 类   | 说明  |
| ---- | ---- |
|QList<T>|这是到目前为止最常用的容器类。它存储一个给定类型(T)的值列表，可以通过索引访问。在内部，它将给定类型的值数组存储在内存中的相邻位置。在列表的前面或中间插入可能会非常慢，因为它可能导致大量项必须在内存中移动一个位置。|
|QVarLengthArray<T, Prealloc>|这提供了一个低级的变长数组。 在速度特别重要的地方，它可以代替QList。|
|QStack<T>|这是QList的一个方便子类，它提供了“后进先出”(LIFO)语义。 它将以下函数添加到QList中:push()、pop()和top()。|
|QQueue<T>|这是QList的一个方便子类，它提供了“先进先出”(FIFO)语义。 它向QList中已经存在的函数添加了以下函数:enqueue()、dequeue()和head()。|
|QSet<T>|这提供了一个具有快速查找功能的单值数学集。|
|QMap<Key, T>|这提供了一个字典（关联数组），它将 Key 类型的键映射到 T 类型的值。通常每个键都与单个值相关联。 QMap 按 Key 顺序存储其数据； 如果顺序无关紧要，QHash 是一个更快的选择。|
|QMultiMap<Key, T>|这是 QMap 的一个便利子类，它为多值映射提供了一个很好的接口，即一个键可以与多个值相关联的映射。|
|QHash<Key, T>|这与 QMap 具有几乎相同的 API，但提供了更快的查找速度。 QHash 以任意顺序存储其数据。|
|QMultiHash<Key, T>|这是 QHash 的一个便利子类，它为多值散列提供了一个很好的接口。|

容器可以嵌套。例如，完全可以使用 QMap<QString, QList<int>>，其中键类型为 QString，值类型为 QList<int>。

存储在各种容器中的值可以是任何可分配的数据类型。要符合条件，类型必须提供一个复制构造函数和一个赋值运算符。对于某些操作，还需要默认构造函数。这涵盖了您可能希望存储在容器中的大多数数据类型，包括 int 和 double 等基本类型、指针类型以及 QString、QDate 和 QTime 等 Qt 数据类型，但不包括 QObject 或任何QObject 子类（QWidget、QDialog、QTimer 等）。如果您尝试实例化 QList<QWidget>，编译器将抱怨 QWidget 的复制构造函数和赋值运算符被禁用。如果要将这些类型的对象存储在容器中，请将它们存储为指针，例如 QList<QWidget *>。

## 遍历容器

Qt提供了两种遍历容器的风格：

**java风格**的迭代器和**stl风格**的迭代器。java风格的迭代器更容易使用并提供高级功能，而STL风格的迭代器稍微更高效，可以与Qt和STL的通用算法一起使用。

+ **java风格**

| 容器                                       | 只读迭代器           | 读写迭代器                  |
| ------------------------------------------ | -------------------- | --------------------------- |
| QList<T>，QVector<T>，QStack<T>，QQueue<T> | QListIterator<T>     | QMutableListIterator<T>     |
| QSet<T>                                    | QSetIterator<T>      | QMutableSetIterator<T>      |
| QMap<Key,T>                                | QMapIterator<T>      | QMutableMapIterator<T>      |
| QMultiMap<Key,T>                           | QMultiMapIterator<T> | QMutableMultiMapIterator<T> |
| QHash<Key,T>，QMultiHash<Key,T>            | QHashIterator<T>     | QMutableHashIterator<T>     |

**范例：**

```cpp
QList<int> list;
list<<1<<2<<3<<4<<5;

QListIterator<int> it(list);
while (it.hasNext())
{
    qInfo()<<it.next();
}
```

+ **STL风格**

| 容器                                       | 只读迭代器                         | 读写迭代器                   |
| ------------------------------------------ | ---------------------------------- | ---------------------------- |
| QList<T>，QVector<T>，QQueue<T>，QStack<T> | QList<T>::const_iterator           | QList<T>::iterator           |
| QVarLengthArray<T>                         | QVarLengthArray<T>::const_iterator | QVarLengthArray<T>::iterator |
| QSet<T>                                    | QSet<T>::const_iterator            | QSet<T>::iterator            |
| QMap<Key,T>                                | QMap<Key,T>::const_iterator        | QMap<Key,T>::iterator        |
| QMultiMap<Key,T>                           | QMultiMap<Key,T>::const_iterator   | QMultiMap<Key,T>::iterator   |
| QHash<Key,T>                               | QHash<Key,T>::const_iterator       | QHash<Key,T>::iterator       |
| QMultiHash<Key,T>                          | QMultiHash<Key,T>::const_iterator  | QMultiHash<Key,T>::iterator  |

**范例：**

```cpp
QList<int> list;
list<<1<<2<<3<<4<<5;
for(QList<int>::Iterator it = list.begin();it!=list.end();it++)
{
    qInfo()<<*it;
}
```



## 序列式容器

### QList/QVector

QList<T>是Qt的通用容器类之一。 它将item存储在相邻的内存位置，并提供快速的基于索引的访问。 QVector<T>曾经是Qt 5中的一个不同的类，但现在是QList的一个简单别名。

QList<T>和QVarLengthArray<T>提供类似的api和功能。 它们通常是可互换的，但会对性能产生影响。 以下是用例概述:

+ QList应该是您的默认首选。
+  QVarLengthArray提供了一个在堆栈上保留空间的数组，但如果需要，可以动态增长到堆上。 它适用于短寿命的小容器。
+  如果您需要一个真正的链表，它保证在链表中间插入的时间是常数，并且对项使用迭代器而不是索引，那么可以使用std::list。

#### 公有函数

+ 添加数据

```cpp
//支持流插入
QList<int>()<<1<<2<<3<<4<<5;
//尾部添加
void append(const T &value)
void append(const QList<T> &value)
void push_back(const T &value)
//头部添加
void prepend(const T &value)
void push_front(const T &value)
//指定位置添加    
QList::iterator insert(qsizetype i, QList::parameter_type value)
QList::iterator insert(qsizetype i, qsizetype count, QList::parameter_type value)
QList::iterator insert(QList::iterator before, const T &value)
```

+ 获取数据

```cpp
T &back()
T &last()

T &first()
T &front()

const T &constFirst() const
const T &constLast() const

//返回下标为i的元素，如果下标i不合法，则返回defaultValue
T value(int i) const
T value(int i, const T &defaultValue) const  
    
const T &at(int i) const
    
T &operator[](int i)
    
//返回从位置pos开始的子列表。如果length为-1(默认)，则包含pos中的所有元素; 
QList<T> mid(int pos, int length = -1) const
```

+ 删除数据

```cpp
//清空list
void clear()

//删除元素   
int removeAll(const T &value)
bool removeOne(const T &value)
void removeAt(int i)
    
void removeFirst()
void pop_front()
    
void removeLast()
void pop_back()
    
//删除索引位置为i的元素并返回它。    
T takeAt(qsizetype i)
QList::value_type takeFirst()
QList::value_type takeLast()
```

+ 查找/替换

```cpp
//返回value在列表中第一次出现的索引位置，从索引位置from向前搜索。 如果没有匹配的项，则返回-1。  
qsizetype indexOf(const AT &value, qsizetype from = 0) const
//返回value在列表中最后一次出现的索引位置，从索引位置from反向搜索。如果from是-1(默认值)，则搜索从最后一项开始。如果没有匹配的项，则返回-1。     
qsizetype lastIndexOf(const AT &value, qsizetype from = -1) const
//将索引位置为i的项替换为value
void replace(qsizetype i, QList::parameter_type value)
//如果列表中包含值的出现，则返回true; 否则返回false。 该函数要求值类型具有operator==()的实现。     
bool contains(const AT &value) const
```

+ 交换/移动

```cpp
//将索引位置from到索引位置to  
//["A", "B", "C", "D", "E", "F"] move(1,4)-> ["A", "C", "D", "E", "B", "F"]
void move(qsizetype from, qsizetype to)

void swap(QList<T> &other)
//交换下标i j的元素    
void swapItemsAt(int i, int j)
```

+ 判断函数

```cpp
int count(const T &value) const
int count() const
int size() const
int length() const

bool empty() const
bool isEmpty() const
//如果列表第一项/后一项等于value,则返回true; 否则返回false。  
bool startsWith(const T &value) const    
bool endsWith(const T &value) const
//预分配空间大小    
void reserve(int alloc)
```

### QStack

QStack<T>是Qt的通用容器类之一。 它为相同类型的项实现堆栈数据结构。

堆栈是后进先出(LIFO)结构。 使用push()将项目添加到堆栈的顶部，并使用pop()从顶部检索项目。 top()函数提供对最上面的项的访问，而不需要删除它。

QStack继承自QList。 QList的所有功能也适用于QStack。 例如，您可以使用isEmpty()来测试堆栈是否为空，并且您可以使用QList的迭代器类(例如，qlisttiterator)遍历QStack。 但除此之外，QStack还提供了三个方便的函数，方便地实现后进先出语义:push()、pop()和top()。

```cpp
T pop()
void push(const T &t)
void swap(QStack<T> &other)
T &top()
const T &top() const
```



### QQueue

QQueue<T>是Qt的泛型容器类之一。 它为相同类型的项实现队列数据结构。

 队列是先进先出(FIFO)结构。 使用enqueue()将条目添加到队列尾部，并使用dequeue()从头部检索条目。 head()函数提供了对头项的访问，而不删除它。

QQueue继承自QList。 QList的所有功能也适用于QQueue。 例如，您可以使用isEmpty()来测试队列是否为空，并且您可以使用QList的迭代器类(例如，qlisttiterator)遍历QQueue。 但除此之外，QQueue还提供了三个方便的函数，使FIFO语义的实现变得很容易:enqueue()、dequeue()和head()。

```cpp
//删除队头并返回它  
T dequeue()
//将值t加到队尾    
void enqueue(const T &t)
//返回队头的引用
T &head()
const T &head() const
    
void swap(QQueue<T> &other)
```



### QStringList

QStringList继承自QList<QString>。 它提供基于索引的快速访问以及快速插入和删除。 将字符串列表作为值参数传递既快速又安全。 
		QList的所有功能也适用于QStringList。 例如，可以使用isEmpty()来测试列表是否为空，还可以调用append()、prepend()、insert()、replace()、removeAll()、removeAt()、removeFirst()、removeLast()和removeOne()等函数来修改QStringList。 此外，QStringList提供了一些方便的函数，使处理字符串列表更容易:  

+ 判断是否包含某个字符串

```cpp
bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
```

+ 过滤：返回包含子字符串str的所有字符串的列表

```cpp
QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
QStringList filter(const QRegularExpression &re) const
```

+ 查找

```cpp
//从左往右查找
qsizetype indexOf(const AT &value, qsizetype from = 0) const
qsizetype indexOf(const QRegularExpression &re, qsizetype from = 0) const
    
//从右往左查找
qsizetype lastIndexOf(const AT &value, qsizetype from = -1) const
qsizetype lastIndexOf(const QRegularExpression &re, qsizetype from = -1) const
```

+ 连接：将QStringList中的所有字符串连接为一个字符串，每个元素由给定的分隔符(可以是空串)分隔。  

```cpp
QString join(const QString &separator) const
QString join(QChar separator) const
```

+ 删除：从QStringList中删除重复的元素。 返回已删除元素的数量。

```cpp
qsizetype removeDuplicates()
```

+ 替换：返回一个字符串列表，其中每个字符串在找到before文本时都将before文本替换为after文本

```cpp
QStringList &replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive)
QStringList &replaceInStrings(const QRegularExpression &re, const QString &after)
```

+ 排序：升序

```cpp
void sort(Qt::CaseSensitivity cs = Qt::CaseSensitive)
```



## 关联式容器

### QMap

QMap<Key, T> 是 Qt 的通用容器类之一。 它存储(键，值)对，并提供与键关联的值的快速查找。
		QMap 和 QHash 提供非常相似的功能。 区别在于：

+ QHash 提供比 QMap 更快的平均查找速度。
+ 在迭代 QHash 时，项目是任意排序的。 使用 QMap，项目总是按键排序。
+ QHash 的键类型必须提供 operator==() 和全局 qHash(Key) 函数。 QMap 的键类型必须提供 operator<() 指定总顺序。 从 Qt 5.8.1 开始，使用指针类型作为键也是安全的，即使底层 operator<() 不提供全序。

#### 公有函数

+ 添加数据

```cpp
//插入新的键值对，如果已经有一个键为key的项，则该项的值将被value替换；如果有多个键为key的项，则最近插入的项的值将被value替换。  
QMap::iterator insert(const Key &key, const T &value)
QMap::iterator insert(QMap::const_iterator pos, const Key &key, const T &value)
void insert(const QMap<Key, T> &map)
void insert(QMap<Key, T> &&map)
```

+ 获取数据

```cpp
T &first()						//获取第一个值
const Key &firstKey() const		//获取第一个键
    
T &last()
const Key &lastKey() const
    
Key key(const T &value, const Key &defaultKey = Key()) const	//根据值获取键

QList<Key> keys() const					//获取所有键
QList<Key> keys(const T &value) const	//获取指定值对应的所有键

T value(const Key &key, const T &defaultValue = T()) const	//获取指定键对应的值
QList<T> values() const										//获取所有值

T &operator[](const Key &key)				
T operator[](const Key &key) const
```

+ 删除数据

```cpp
void clear()

QMap::size_type remove(const Key &key)
QMap::size_type removeIf(Predicate pred)
    
T take(const Key &key)
```

+ 查找

```cpp
bool contains(const Key &key) const
/* 返回两个迭代器
迭代器1：是指向当前 map 容器中第一个等于(如果没有找到，就找或大于的第一个) key 的键值对的迭代器（lowerBound()）。
迭代器2：是指向当前 map 容器中第一个大于 key 的键值对的迭代器。（upperBound()）
*/
QPair<QMap::iterator, QMap::iterator> equal_range(const Key &key)
    
QMap::iterator find(const Key &key)

QMap::iterator lowerBound(const Key &key)
QMap::iterator upperBound(const Key &key)
```

+ 判断

```cpp
QMap::size_type count(const Key &key) const
QMap::size_type count() const
QMap::size_type size() const
    
bool empty() const
bool isEmpty() const
```



### QMultiMap

QMultiMap<Key, T>是Qt的通用容器类之一。 它存储(键、值)对，并根据键提供快速查找。

该类大部分函数和QMap一样，除了下面新增的几个。

+ 移除，比QMap多了一个

```cpp
QMultiMap::size_type remove(const Key &key, const T &value)
```

+ 替换
  + 如果已经有一个键为key的项，则该项的值将被value替换。 
  + 如果有多个键为key的项，则最近插入的项的值将被value替换。  

```cpp
 QMultiMap::iterator replace(const Key &key, const T &value)
```

+ 合并：把other合并到当前map

```cpp
 QMultiMap<Key, T> &unite(const QMultiMap<Key, T> &other)
 QMultiMap<Key, T> &unite(QMultiMap<Key, T> &&other)
```



### QHash

+ 添加数据

```cpp
 QHash::iterator insert(const Key &key, const T &value)
 void insert(const QHash<Key, T> &other)
```

+ 获取数据

```cpp
Key key(const T &value, const Key &defaultKey = Key()) const

QList<Key> keys() const
QList<Key> keys(const T &value) const
   
 T value(const Key &key, const T &defaultValue = T()) const
 QList<T> values() const
```

+ 删除数据

```cpp
void clear()

bool remove(const Key &key)
qsizetype removeIf(Predicate pred)

T take(const Key &key)
```

+ 查找

```cpp
bool contains(const Key &key) const
    
QHash::iterator find(const Key &key)
```

+ 判断

```cpp
qsizetype count(const Key &key) const
qsizetype count() const
qsizetype size() const
    
bool empty() const
bool isEmpty() const    
```

### QMultiHash

QMultiHash<Key, T>是Qt的通用容器类之一。 它继承了QHash，并通过一些方便的函数对其进行扩展，使其比QHash更适合存储多值哈希。 多值散列是一种允许具有相同键的多个值的散列。

 QMultiHash主要镜像QHash的API。 例如，您可以使用isEmpty()来测试散列是否为空，并且您可以使用QHash的迭代器类(例如，QHashIterator)遍历QMultiHash。 但与QHash不同的是，它提供了一个insert()函数，该函数允许插入具有相同键的多个项。 replace()函数对应于QHash::insert()。 它还提供了方便的operator+()和operator+=()。

与QMultiMap不同，QMultiHash不提供插入项的排序。 唯一的保证是共享相同密钥的项将连续出现，从最近插入的值到最近插入的值。

+ 移除

```cpp
 qsizetype remove(const Key &key, const T &value)
```

+ 替换

```cpp
typename QHash<Key, T>::iterator replace(const Key &key, const T &value)
```

+ 案例

```cpp
class Grade //班级
{
public:
    Grade(int number, const QString& GradeName)
        :number(number),name(GradeName)
    {}
    friend QDebug operator<<(QDebug out, const Grade& stu);
    friend bool operator==(const Grade& left, const Grade& right);
    friend uint qHash(const Grade& stu, uint seed = 0);
private:
    int number;     //班级号
    QString name;   
};
QDebug operator<<(QDebug out, const Grade& stu)
{
    out << "[" << stu.number <<"," << stu.name << "]";
    return out;
}
bool operator==(const Grade& left, const Grade& right)
{
    return (left.number == right.number);
}
uint qHash(const Grade& stu, uint seed)
{
    return stu.number;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QHash<Grade, QString> hash;
    hash.insert(Grade(1403, "安卓"), "张三");
    hash.insert(Grade(1406, "苹果"), "李四");

    qDebug() << hash;

    return a.exec();
}
```



### QSet

QSet<T>是Qt的泛型容器类之一。 它以不指定的顺序存储值，并提供非常快速的值查找。 在内部，QSet<T>被实现为一个QHash。

+ 添加数据

```cpp
QSet::iterator insert(const T &value)
QSet::iterator insert(QSet::const_iterator it, const T &value)
```

+ 获取数据

```cpp
QList<T> values() const
```

+ 删除数据

```cpp
void clear()

bool remove(const T &value)
```

+ 查找

```cpp
bool contains(const T &value) const
bool contains(const QSet<T> &other) const
    
QSet::const_iterator find(const T &value) const
QSet::iterator find(const T &value)
```

+ 其他

```cpp
int count() const
bool empty() const
bool isEmpty() const
int size() const
```

+ 交集，差集，并集

```cpp
//并集：ohter集合中不在这个集合中的每一项都被插入到这个集合中。 返回对该集合的引用。      
QSet<T> &unite(const QSet<T> &other)
//差集：从该集合中删除包含在ohter集合中的所有项。 返回对该集合的引用。  
QSet<T> &QSet::subtract(const QSet<T> &other)
//交集：从该集合中删除ohter集合中不包含的所有项。 返回对该集合的引用。      
QSet<T> &intersect(const QSet<T> &other)
//如果该集合与ohter集合至少有一个共同项，则返回true。      
bool intersects(const QSet<T> &other) const 
```

# 8，算法

直接使用STL中的算法

## QtGlobal

Qt类的头文件都会包含该头文件，所以不用再显式定义了

```cpp
T qAbs(const T &t)	//求绝对值
//返回value限定在min至max范围之内的值
const T &qBound(const T &min, const T &val, const T &max)
//如果p1和p2近似相等，返回true
bool qFuzzyCompare(double p1, double p2)
bool qFuzzyCompare(float p1, float p2)
//如果浮点数约等于0，返回true    
bool qFuzzyIsNull(double d)
bool qFuzzyIsNull(float f)
//返回无穷大的数    
double qInf()
//求最大值和最小值
const T &qMax(const T &a, const T &b)
const T &qMin(const T &a, const T &b)
//四舍五入到最近的整数
qint64 qRound64(double d)
qint64 qRound64(float d)
int qRound(double d)
int qRound(float d)
//获得Qt版本    
const char *qVersion()
```



## QtMath

### 常用函数

```cpp
qreal qAcos(qreal v)			//以弧度角的形式返回 v 的反余弦值。 反余弦是余弦的逆运算。
qreal qAsin(qreal v)			//以弧度角的形式返回 v 的反正弦值。 反正弦是正弦的逆运算。
qreal qAtan2(qreal y, qreal x)	//返回由坐标 y 和 x 指定的点的反正切。 此函数将返回该点的角度（参数）。
qreal qAtan(qreal v)	//以弧度角的形式返回 v 的反正切。 反正切是正切的逆运算。

qreal qSin(qreal v)		//返回以弧度为单位的角v的正弦值
qreal qCos(qreal v)		//返回以弧度为单位的角v的余弦值。
qreal qTan(qreal v)		//返回以弧度为单位的角v的正切。
//此函数将浮点度数(角度)转换为弧度。   
float qDegreesToRadians(float degrees)
double qDegreesToRadians(double degrees)
//这个函数将浮点数radians弧度转换为角度。   
float qRadiansToDegrees(float radians)		
double qRadiansToDegrees(double radians)

qreal qExp(qreal v)		//返回 e 的 v 次幂的指数函数
qreal qFabs(qreal v)	//返回v的绝对值。

int qCeil(qreal v)		//返回值v的上限。上限值是不小于v的最小整数。例如，如果v是41.2，那么上限值是42
int qFloor(qreal v)		//返回值 v 的下限。下限是不大于 v 的最大整数。例如，如果 v 为 41.2，则下限为 41

//求直角三角形的斜边    
auto qHypot(F first, Fs... rest)
auto qHypot(Tx x, Ty y)
auto qHypot(Tx x, Ty y, Tz z)

quint32 qNextPowerOfTwo(quint32 value)	//这个函数返回比value大的2的最近幂。 对于0，它返回1，对于大于或等于2^31的值，它返回0。
quint64 qNextPowerOfTwo(quint64 value)
quint32 qNextPowerOfTwo(qint32 value)
quint64 qNextPowerOfTwo(qint64 value)
    
qreal qPow(qreal x, qreal y)				//返回x的y次方的值。也就是说，x是底数，y是指数。
qreal qSqrt(qreal v)						//返回v的平方根。如果v是负数，则返回NaN。
qreal qLn(qreal v)							//返回v的自然对数。自然对数以e为底。    
```

### 宏

| 宏         | 含义                    |
| ---------- | ----------------------- |
| M_E        | 自然对数的底 e = exp(1) |
| M_LOG2E    | 以2为底e的对数          |
| M_LOG10E   | 以10为底的e的对数       |
| M_LN2      | 2的自然对数             |
| M_LN10     | 10的自然对数            |
| M_PI       | π                       |
| M_PI_2     | π/2                     |
| M_PI_4     | π/4                     |
| M_1_PI     | 1/π                     |
| M_2_PI     | 2/π                     |
| M_2_SQRTPI | 2除以π的平方根，2 /√π   |
| M_SQRT2    | 根号2                   |
| M_SQRT1_2  | 1/√π                    |



