嵌入式学习-QT-Day05
[1.1 顺序容器------QList类](#1.1 顺序容器——QList类)
[1.2 关联容器------QMap类](#1.2 关联容器——QMap类)
[3.1 跨平台数据类型](#3.1 跨平台数据类型)
[3.2 QVariant统一变量类](#3.2 QVariant统一变量类)
[3.3 QStringList字符串列表](#3.3 QStringList字符串列表)
五、常用类
1、容器类
Qt重写了C++的STL中的容器类,相比于C++STL的容器类,Qt的容器类更轻巧、安全、易于使用。因为Qt的容器类进行了速度和存储的优化,减少了可以执行文件的生成体积,几乎全面兼容STL容器类的API接口,并且是线程安全的,可以同时被多个线程访问。
1.1 顺序容器------QList类
本次课程使用QList类存储Student元素,Student是自定义C++类型,在Qt项目中创建一个C++的操作步骤如下:
- 在Qt Creator中选中项目名称,鼠标右键,点击添加"新文件"。
- 在弹出的窗口中,按照下图所示进行操作。
在弹出的窗口中输入类名(帕斯卡/大驼峰)
在项目管理页面直接点击完成,可以看到新建的文件在项目中存在了。
student.h
#ifndef STUDENT_H`
`#define STUDENT_H`
`#include <QString>`
`class Student`
`{`
`public:`
` Student(int,QString,QString);`
` ~Student();`
` int getId() const;`
` void setId(int value);`
` QString getName() const;`
` void setName(const QString &value);`
` QString getMajor() const;`
` void setMajor(const QString &value);`
`private:`
` int id; // 编号`
` QString name; // 姓名`
` QString major; // 专业`
`};`
`#endif // STUDENT_H`
`
student.cpp
#include "student.h"`
`Student::Student(int id, QString name, QString major)`
` :id(id),name(name)`
`{`
` this->major = major;`
`}`
`Student::~Student()`
`{`
`}`
`int Student::getId() const`
`{`
` return id;`
`}`
`void Student::setId(int value)`
`{`
` id = value;`
`}`
`QString Student::getName() const`
`{`
` return name;`
`}`
`void Student::setName(const QString &value)`
`{`
` name = value;`
`}`
`QString Student::getMajor() const`
`{`
` return major;`
`}`
`void Student::setMajor(const QString &value)`
`{`
` major = value;`
`}`
`
dialog.h
#ifndef DIALOG_H`
`#define DIALOG_H`
`#include <QDialog>`
`#include <QList>`
`#include <QDebug>`
`#include "student.h"`
`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)`
`{`
` ui->setupUi(this);`
` // 创建QList对象`
` QList<Student> lis;`
` Student s1(1,"金有","物联网");`
` Student s2(2,"金璇","母猪产后护理");`
` Student s3(3,"小孩哥","导弹维修");`
` Student s4(4,"王某","王警");`
` Student s5(5,"够级王","赌神");`
` // 向后插入元素(链式调用)`
` lis << s1 << s2 << s3 << s4;`
` // 插入`
` lis.insert(1,s5); // 在第二个位置上插入的s5`
` // 删除`
` lis.removeFirst(); // 删除第一个`
` lis.removeLast(); // 删除最后一个`
`// lis.removeOne(s2); // 编译操作,不支持自定义类型比较,如果想要实现此功能,需要将==运算符进行重载。删除所有相同元素的第一个`
`// lis.removeAll(s3); // 删除所有相同的元素`
` lis.removeAt(1); // 删除第二个元素`
` // 遍历`
` for(int i = 0; i < lis.count(); i++)`
` {`
` Student s = lis.at(i);`
` qDebug() << s.getId() << s.getName() << s.getMajor();`
` }`
`// 迭代器遍历C++`
` for(QList<Student>::iterator iter = lis.begin(); iter != lis.end();iter++)`
` {`
` Student s = *iter;`
` qDebug() << s.getId() << s.getName() << s.getMajor();`
` }`
`}`
`Dialog::~Dialog()`
`{`
` delete ui;`
`}`
`
1.2 关联容器------QMap类
重新实现了STL中std::map类,QMap也兼容map类的api,也增加了一些新的Qt的API。
dialog.h
#ifndef DIALOG_H`
`#define DIALOG_H`
`#include <QDialog>`
`#include <QMap>`
`#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)`
`{`
` ui->setupUi(this);`
` QMap<QString,QString>map; // 创建一个栈内存对象`
` // 插入数据`
` map.insert("姓名","智彬");`
` map.insert("年龄","18");`
` map.insert("地址","地球村");`
` map.insert("爱好","美女");`
` map.insert("专业","开挖掘机");`
` map.insert("身高","200");`
` map.insert("体重","200");`
` // 如果容器中的元素支持QDebug输出,则容器本身也支持输出`
` qDebug() << map;`
` // 删除键值对`
` // 返回值为删除的键值对数量`
` qDebug() << map.remove("体重"); // 1`
` qDebug() << map.remove("体重"); // 0`
` // 判断某个键值对存不存在`
` qDebug() << map.contains("体重"); // false`
` if(map.contains("地址"))`
` {`
` map["地址"] = "济南市";`
` }`
` // 取出元素,第二个参数,如果没有找到对应key就会输出第二个参数`
` qDebug() << map.value("身高","没有没有");`
` qDebug() << map.value("身高2","没有没有");`
` // STL 迭代器 C++`
` for(QMap<QString,QString>::iterator iter = map.begin();iter != map.end();iter++)`
` {`
` // 输出键值对`
` qDebug() << iter.key() << iter.value();`
` }`
` qDebug() << map;`
`}`
`Dialog::~Dialog()`
`{`
` delete ui;`
`}
2、QString字符串类
QString是Qt的字符串类,与C++std::string相比,不再使用ASCII编码,QString使用的是Unicode编码。
QString中每个字符都是16位QChar,而不是8位的char。
QString完全支持中文,但是由于不同的技术可能会采用不同的中文编码,有时候也会出现中文编码一致性的问题。
如果后续的学习、或工作中遇到中文的编码问题,请参考:
Qt中对C++的类尽心重写时,充分考了到了C++程序员的编程习惯,因此QString几乎支持std::string所有的API。除此之外也会新增一些函数。
// int -> QString`
`// 参数1:转换的原始数据`
`// 参数2:转换的进制`
`QString QString::number(int n, int base = 10)[static]
// QString -> int`
`// 参数1:转换成功还是失败,成功参数为true,失败参数设置为false`
`// 参数2:进制`
`// 返回值:转换后的int数值,转换失败返回0`
`int QString::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(); // 12`
` // int -> QString`
` int a = 255;`
` qDebug() << QString::number(a,16); // FF`
` // QString -> int`
` bool result = false;`
` str = "0";`
` qDebug() << str.toInt(&result); // 0`
` qDebug() << result; // true`
` str = "我是一个错误的字符串";`
` qDebug() << str.toInt(&result); // 0`
` qDebug() << result; // false`
`// ui->textBrowser->setText(str);`
`}`
`Dialog::~Dialog()`
`{`
` delete ui;`
`}`
`
不建议死记硬背QString的API,因为数量多且有示例代码,只需要把常用的关键字记住即可。
3、Qt数据类型
3.1 跨平台数据类型
Qt是一个跨平台的开发框架,所以必须要保证各个平台的数据类型长度保持一致,因此Qt为常见的基本数据类型重新定义了新的类型符号。
在Qt的环境下,可以直接使用。
3.2 QVariant统一变量类
QVariant类型可以与Qt常见的数据类型完成相互转换,因此此类型的函数具有类似于多态的性质。
dialog.cpp
#include "dialog.h"`
`#include "ui_dialog.h"`
`Dialog::Dialog(QWidget *parent) :`
` QDialog(parent),`
` ui(new Ui::Dialog)`
`{`
` ui->setupUi(this);`
` qint64 a = 123;`
` QVariant v(a);`
` QString str = v.toString(); // 转换成字符串`
` qDebug() << str;`
` v = str;`
` int b = v.toInt(); // 转换成int`
` qDebug() << b;`
`}`
`Dialog::~Dialog()`
`{`
` delete ui;`
`}`
`
3.3 QStringList字符串列表
几乎相当于QList<QString>
4、时间与日期的处理
Qt中使用QDate类处理日期,使用QTime类处理时间,使用QDateTime类处理时间和日期。
需要注意的是,QDateTime的数据来自于系统日期和时间,所以修改时间会影响到QDateTime的数据。
常用函数如下:
// 返回1970年1月1日00:00:00到现在的毫秒数`
`qint64 QDateTime::currentMSecsSinceEpoch()[static]
时间戳的作用,计算代码的运算时间。
时间戳的其他作用:
可以使用时间戳作为随机数的种子,但是需要注意,我们计算机的随机数都是伪随机,不是真正的随机数。计算机无法做到真正的随机数。
获取当前的日期时间对象。
// 返回一个包含当前日期和时间的QDateTime对象`
`QDateTime QDateTime::currentDateTime()[static]
// 格式化输出年月日、时分秒`
`QString QDateTime::toString(const QString & format) const
秒:ss
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);`
` // 生成随机数(0-100)`
` qDebug() << qrand() % 101;`
` QDateTime dt = QDateTime::currentDateTime();`
` qDebug() << dt.toString("yy年MM月dd日 hh时mm分ss秒");`
`}`
`Dialog::~Dialog()`
`{`
` delete ui;`
`}`
`
其他和日期时间相关的组件:
5、QTimer定时器类
QTimer类可以实现一个延时任务或者周期任务。
使用定时器,需要包含头文件include<QTimer>。定时器继承自QObject。
QTimer的常用属性:
- interval : int
时间间隔,单位为毫秒。
- singleShot : bool
是否一次性
- active : const bool
当前定时器的运行状态。
QTimer类的常用函数:
// 构造函数,堆区创建`
`QTimer::QTimer(QObject * parent = 0)
QLcdNumber组件
使用这个组件,显示出15:00:31 这样的时间。
因为显式时间需要8位,所以需要将此属性改为8
// QLCDNumber 的显式槽函数`
`void display(const QString & s)[slot]`
`
这个组件,无法显式中文,但是可以显式部分英文。
实现显式时间功能
// 定时器触发时,发射的信号`
`void QTimer::timeout()[signal]
// 启动定时器`
`void QTimer::start()[slot]
// 关闭定时器`
`void QTimer::stop()[slot]
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;`
`private:`
` 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(500);`
` // 是否为一次性`
` timer->setSingleShot(false);`
` // 连接信号槽要在定时器启动之前,连接`
` connect(timer,SIGNAL(timeout()),`
` this,SLOT(timeOutSlot()));`
` // 启动定时器`
` timer->start();`
`}`
`Dialog::~Dialog()`
`{`
` if(timer->isActive()) // 如果正在运行,则先关闭`
` {`
` timer->stop();`
` }`
` delete timer;`
` delete ui;`
`}`
`void Dialog::timeOutSlot()`
`{`
` // 获取当前时间,转换为时:分:秒 格式的QString字符串`
` QString str = QDateTime::currentDateTime().toString("hh:mm:ss");`
` ui->lcdNumber->display(str);`
`}`
`