C++常用类

1、QString 字符串类

QString 是Qt的字符串类,与C++的std::string相比,不再使用ASCII编码。QString使用的Unicode编码

QString 完全支持中文, 但是由于不同的技术可能会采用不同的编码。有时候也会遇到中文编码的一致性问题。

如果后续的学习或者工作中遇到编码出现中文乱码问题,请参考:

从此乱码是路人

QString中每字符都是一个16位QChar,而不是8位的char。

Qt中的QString对C++的std::string类进行了重写时,充分考虑到了C++程序员的编程习惯,因此QString几乎支持所有std::string的API。除此之外,也会新增一些API。

复制代码
// int -> QString`
`// 参数1:要转换的数字`
`// 参数2:进制`
`// 返回值:转换后的QString 对象`
`QString`	`number(int n,` `int` `base` `=` `10`

`
复制代码
// int → QString`
`// 参数1:要转换的数字`
`// 参数2:进制`
`// 返回值:转换后的当前对象,支持链式调用`
`QString &` `QString::setNum(int n,` `int base =` `10)`
`
复制代码
// QString -> int`
`// 参数1:转换成功或失败,成功设置成true,失败设置为false`
`// 参数2:进制`
`// 返回值:转换后的结果,失败的话返回0`
`int`	`toInt(bool` `* ok =` `0,` `int` `base` `=` `10)` `const`
`

dialog.cpp

复制代码
#include "dialog.h"`
`#include "ui_dialog.h"`

`Dialog::Dialog(QWidget *parent) :`
`    QDialog(parent),`
`    ui(new Ui::Dialog)`
`{`
`    ui->setupUi(this);`
`    QString str = "你好";`
`    qDebug()<<str;`
`    qDebug()<<str.size();`
`    //int->QString`
`    int a=255;`
`    qDebug()<<QString::number(a,10);`
`    qDebug()<<QString::number(a,8);`
`    qDebug()<<QString::number(a,16);`
`    qDebug()<<QString::number(a,2);`
`    //字符转int`
`    bool resule = false;`
`    str = "0";`
`    qDebug()<<str.toInt(&resule);//0 原始数据为0,需要传参验证是否转换成功`
`    qDebug() << resule;//true=1`
`    str = "22aa";`
`    qDebug()<<str.toInt(&resule);//0 转换失败`
`    qDebug() << resule;//false = 0`
`}`
`Dialog::~Dialog()`
`{`
`    delete ui;`
`}`

`

不建议死记QString的API,因为数量较多且都有示例代码,只需要把常用函数的关键词记住即可:

2、容器类

Qt重写了C++的STL中的容器类,相比较于C++STL的容器,Qt的容器类更轻巧,安全和易于使用。因为Qt的容器类进行了速度和存储的优化,较少了可执行文件的生成体积。几乎兼容C++STL容器类所有API接口,并且是线程安全的,可以同时被多个线程所访问。

2.1 顺序容器------QList类

本次课程内容使用QList容器存储Student元素。Student是自定义数据类型,在Qt项目中创建一个C++类的文件。

  1. 在Qt Creator中选中项目名称,鼠标右键,点击添加"新文件"

2、在弹出的窗口中,选择"C++ class",点击"选择"

  1. 在弹出的窗口中输入类名(帕斯卡/大驼峰命名法)
  1. 在项目管理界面中点击"完成"。可以看到新的文件在项目中存在了。
自动添加构造函数

在对象头文件中添加成员变量,以下操作可以自动在头函数中声明get和set成员函数,在对象文件中初始化相关成员函数。

student.h中声明,student.cpp中实现dialog.cpp中调用,调用时注意添加自定义类的头函数,并表明作用域。赋值

删除插入对象:
三种对象遍历方式
for遍历
复制代码
//遍历`
`    for(int i=0;i < lis.count();i++)`
`    {`
`        Student s = lis.at(i);`
`        qDebug()<<s.getId()<<s.getName()<<s.getMajor();`
`    }`
`
c++迭代器遍历
复制代码
//C++迭代器 遍历,本质还是for循环,用iter迭代器指针遍历,指针开始指向对象头,结束指向对象尾。`
`    for(QList<Student>::iterator iter = lis.begin();`
`    iter != lis.end();iter++)`
`    {`
`        Student s = *iter;`
`        qDebug()<<s.getId()<<s.getName()<<s.getMajor();`
`    }`
`
JAVA迭代器遍历
复制代码
//JAVA迭代器,参数为容器对象`
`    QListIterator<Student> iter(lis);`
`    while(iter.hasNext())//判断当前迭代器指针后面是否有可用元素`
`    {`
`        Student s = iter.next(); // 向后移动迭代器指针并取出元素`
`        qDebug()<<s.getId()<<s.getName()<<s.getMajor();`
`    }`
`

2.2 关联容器------QMap类

重新实现了STL中std::map类,QMap也兼容map类的API,也增加了一些新的Qt的API。

插入操作:
删除操作:
查找/修改键值对:
取出元素:
直接遍历:
迭代器遍历:
JAVA迭代器遍历:(只读/读写)

dialog.h

复制代码
#ifndef DIALOG_H`
`#define DIALOG_H`

`#include <QDialog>`
`#include <QMap>`
`#include <QDebug>`

`class` `Dialog` `:` `public QDialog`
`{`
`    Q_OBJECT`

`public:`
    `Dialog(QWidget *parent =` `0);`
    `~Dialog();`
`};`

`#endif // DIALOG_H`

`

dialog.cpp

复制代码
#include "dialog.h"`

`Dialog::Dialog(QWidget *parent)`
`    : QDialog(parent)`
`{`
`    QMap<QString,QString> map;//创建一个栈内存对象`
`    //插入数据`
`    map.insert("姓名","张三");`
`    map.insert("年龄","18");`
`    map.insert("地址","济南");`
`    map.insert("专业","总裁");`
`    map.insert("身高","185");`
`    map.insert("爱好","女");`
`    //如果容器中的元素支持qDebug输出,则容器本身也支持输出`
`    qDebug()<<map;`
`    //删除键值对,返回值为删除的键值对数量`
`    qDebug()<<map.remove("专业");//1`
`    qDebug() << map.remove("专业"); // 0,删除失败返回0`
    
`    //查找键值对`
`    if(map.contains("专业"))`
`    {`
`        map["专业"]="富二代";`
`    }`
`    else`
`    {`
`        qDebug()<<"没有找到";`
`    }`

`    if(map.contains("地址"))`
`    {`
`        map["地址"]="地球";`
`    }`
`    else`
`    {`
`        qDebug()<<"没有找到";`
`    }`

`    qDebug()<<map;`
`    //取出元素,返回值为value,参数1:key,`
`    //参数2:如果没有找到对应的key就会输出第二个参数。`
`    qDebug()<<map.value("身高","没有找到");`
`    qDebug()<<map.value("专业","没有找到2");`

`    //迭代器遍历`
`    for(QMap<QString,QString>::iterator iter = map.begin();`
`        iter != map.end();iter++)`
`    {`
`        //输出键与值`
`        qDebug()<<iter.key()<<iter.value();`
`    }`
`    //JAVA迭代器`
`    //读写迭代器:QMutableMapIterator<key,T>`
`    //只读迭代器:QMapIterator<key,T>`
`    QMapIterator<QString,QString> iter(map);`
`    while(iter.hasNext())`
`    {`
`        iter.next();`
`        //输出键与值`
`        qDebug()<<iter.key()<<iter.value();`
`    }`

`}`

`Dialog::~Dialog()`
`{`

`}`

`

3、Qt数据类型

3.1 跨平台数据类型

Qt是一个跨平台的开发框架,所以必须要保证各个平台的数据类型长度保持一致,因此Qt为最常见的数据类型提供了新的定义。

在Qt的环境下,可以直接使用。

3.2 QVariant 统一变量类

QVariant类型可以与Qt常见的数据类型完成相互转换,因此此类型的函数具有类似于多态的性质。

dialog.cpp

复制代码
#include "dialog.h"`
`Dialog::Dialog(QWidget *parent)`
    `:` `QDialog(parent)`
`{`
    `qint64 a =` `123;`
    `QVariant` `v(a);`
    `QString s = v.();` `// 转换成字符串`
    `qDebug()` `<< s ;` `// 字符串:"123"`
`    v = s;`
    `int b = v.toInt();`   `// 转换成int`
    `qDebug()` `<< b ;` `// 整形:123`
`}`
`Dialog::~Dialog()`
`{`

`}`

`

3.3 QStringList字符串列表

几乎相当于QList<QString>

复制代码
QList<QString>` `str={"AAAA","BBBB","CCCC"};`
`

4、时间与日期处理

Qt中用QDate类处理日期,使用QTime类处理时间,使用QDateTime类处理时间和日期。以QDateTime为例进行讲解。

需要注意的是,QDateTime的数据来源于系统日期和时间,所以修改系统时间会影响到QDateTime的数据。

1)获取 1970年1月1日00:00:00到现在的毫秒数函数

复制代码
// 返回1970年1月1日00:00:00到现在的毫秒数`
`qint64 QDateTime:: currentMSecsSinceEpoch()[static]`
`

2)用处

1、时间戳的作用,计算代码的运算时间。

  1. 时间戳的其他作用:

时间戳可以作为随机数的种子。但是需要注意的是,我们的计算机的随机数都是伪随机。不是真正的随机数。计算机无法做到真正的随机数。

3)获取当前的日期时间对象

复制代码
// 返回一个包含当前日期和时间的qDateTime对象`
`QDateTime QDateTime:: currentDateTime()[static]`
`

4)当拿到当前日期和时间的对象后,可以提取当前的日期和时间

复制代码
// 参数为格式化输出年月日、时分秒`
`QString QDateTime:: toString(const QString & format) const`
`

秒:ss

大写月份;MMMM

星期:dddd

dialog.h

复制代码
#ifndef DIALOG_H`
`#define DIALOG_H`

`#include <QDialog>`
`#include <QDateTime>`
`#include <QDebug>`

`namespace Ui {`
`class Dialog;`
`}`

`class Dialog : public QDialog`
`{`
`    Q_OBJECT`

`public:`
`    explicit Dialog(QWidget *parent =` `0);`
`    ~Dialog();`

`private:`
`    Ui::Dialog *ui;`
`};`

`#endif // DIALOG_H`

`

dialog.cpp

复制代码
#include "dialog.h"`
`#include "ui_dialog.h"`

`Dialog::Dialog(QWidget *parent)` `:`
`    QDialog(parent),`
`    ui(new Ui::Dialog)`
`{`
`    qint64 start = QDateTime::currentMSecsSinceEpoch();`
`    ui->setupUi(this);`
`    qDebug()` `<< QDateTime::currentMSecsSinceEpoch() - start;`
`    // 使用时间戳作为随机数的种子`
`    qsrand(start);`
`    // 生成随机数种子 生成(1-100)随机数`
`    qDebug()` `<< qrand()%101;`

`    QDateTime dt = QDateTime::currentDateTime();`
`    qDebug()` `<< dt.toString("yyyy年MM月dd日 hh时mm分ss秒");`

`}`

`Dialog::~Dialog()`
`{`
`    delete ui;`
`}`

`
开了两个Qt报错

5)其他的日期和时间相关的UI组件:

1、QTimeEdit

2、QDateEdit

  1. QDateTimeEdit

4、QCalendar

5、QTimer定时器类

QTimer类可以实现一个延时任务或者周期任务。

使用定时器,需要包含头文件#include<QTimer>。定时器类继承自QObject。

QTimer的常用属性有:

  • interval : int

时间间隔,单位毫秒

  • singleShot : bool

是否是一次性

  • active : const bool

当前定时器的运行状态QLCDNumber 组件

使用这个组件,显示出11:31:30 这样的时间

定时器常用函数:

复制代码
// 构造函数 堆区开辟`
`QTimer::` `QTimer(QObject * parent =` `0)`
`
复制代码
// QLCDNumber 的显示槽函数`
`void`	`display(const QString & s)[slot]`
`
复制代码
// 启动定时器,如果定时器已经存在,则会重启`
`void` `QTimer::` `start()[slot]`
`
复制代码
// 定时器触发时,发送的信号`
`void` `QTimer::` `timeout()[signal]`
`
复制代码
// 停止定时器`
`void` `QTimer::` `stop()`
`

dialog.h

复制代码
#ifndef DIALOG_H`
`#define DIALOG_H`

`#include <QDialog>`
`#include <QTimer>`
`#include <QDateTime>`

`namespace Ui {`
`class` `Dialog;`
`}`

`class` `Dialog` `:` `public QDialog`
`{`
`    Q_OBJECT`

`public:`
    `explicit` `Dialog(QWidget *parent =` `0);`
    `~Dialog();`

`private:`
`    Ui::Dialog *ui;`
`    QTimer *timer;`

`private slots:`
    `void` `timeoutSlot();`
`};`

`#endif // DIALOG_H`

`

dialog.cpp

复制代码
#include "dialog.h"`
`#include "ui_dialog.h"`

`Dialog::Dialog(QWidget *parent)` `:`
    `QDialog(parent),`
    `ui(new Ui::Dialog)`
`{`
`    ui->setupUi(this);`
    `// 创建定时器对象`
`    timer =` `new` `QTimer(this);`
    `// 提前刷新显示控件`
    `timeoutSlot();`
    `// 设置定时器参数(时间周期)`
`    timer->setInterval(1000);`
    `// 设置周期循环`
`    timer->setSingleShot(false);`
    `// 信号槽连接,连接要在定时器启动之前`
    `connect(timer,SIGNAL(timeout()),this,SLOT(timeoutSlot()));`
    `// 启动定时器`
`    timer->start();`
`}`

`Dialog::~Dialog()`
`{`
    `if(timer->isActive())`   `// 如果正在运行,则关闭`
    `{`
`        timer->stop();`
    `}`
    `delete ui;`
    `delete timer;`
`}`

`void` `Dialog::timeoutSlot()`
`{`
`    QString str =` `QDateTime::currentDateTime().toString("hh:mm:ss");`
`    ui->lcdNumber->display(str);`
`}`

`
相关推荐
Geek之路20 分钟前
QT-多线程、线程池的使用
qt·多线程
瞌睡不来36 分钟前
(刷题记录5)盛最多水的容器
c++·笔记·学习·题目记录
凯子坚持 c37 分钟前
C语言复习概要(四)
c语言·开发语言
何陈陈1 小时前
【Linux】线程池
linux·服务器·开发语言·c++
清风玉骨1 小时前
Qt-QHBoxLayout布局类控件(42)
开发语言·qt
夏旭泽1 小时前
C-include
开发语言·c++
通信仿真实验室1 小时前
MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
开发语言·算法·matlab
感谢地心引力1 小时前
【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)
c++·windows·python·qt·visual studio
通信仿真实验室1 小时前
(15)衰落信道模型作用于信号是相乘还是卷积
开发语言·人工智能·算法·matlab
远望樱花兔2 小时前
【d59】【Java】【力扣】146.LRU缓存
java·开发语言·算法