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++类的文件。
- 在Qt Creator中选中项目名称,鼠标右键,点击添加"新文件"
2、在弹出的窗口中,选择"C++ class",点击"选择"
- 在弹出的窗口中输入类名(帕斯卡/大驼峰命名法)
- 在项目管理界面中点击"完成"。可以看到新的文件在项目中存在了。
自动添加构造函数
在对象头文件中添加成员变量,以下操作可以自动在头函数中声明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、时间戳的作用,计算代码的运算时间。
- 时间戳的其他作用:
时间戳可以作为随机数的种子。但是需要注意的是,我们的计算机的随机数都是伪随机。不是真正的随机数。计算机无法做到真正的随机数。
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
- 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);`
`}`
`