嵌入式学习-QT-Day05
嵌入式学习-QT-Day05
五、常用类
1、容器类
1.1 顺序容器——QList类
1.2 关联容器——QMap类
2、QString字符串类
3、Qt数据类型
3.1 跨平台数据类型
3.2 QVariant统一变量类
3.3 QStringList字符串列表
4、时间与日期的处理
5、QTimer定时器类
五、常用类
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);
}