五、常用类
- 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 number(int n, int base = 10)
// int → QString
// 参数1:要转换的数字
// 参数2:进制
// 返回值:转换后的QString
QString & setNum(int n, int base = 10)
// QString → int
// 参数1:转换成功或失败,成功设置为true、失败参数设置为false
// 参数2:进制
// 返回值:转换后的int数值。转换失败返回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 = "안녕하세요";
// int -> QString 静态成员函数
int a = 255;
qDebug() << QString::number(a);
qDebug() << QString::number(a,2);
qDebug() << QString::number(a,16);
qDebug() << QString::number(a,8);
// int → QString 成员函数
qDebug() << str.setNum(a);
// QString -> int
bool result = false;
str = "hello";
qDebug() << str.toInt(&result);
qDebug() << result ;
}
Dialog::~Dialog()
{
delete ui;
}
2、容器类
Qt重写了C++的STL中的容器类,相比较于C++STL的容器类,Qt的容器类更加轻巧,安全和易于使用。因为Qt的容器类进行了速度和存储化的优化,减少了可执行文件的生成体积,几乎全面兼容STL容器类的API接口。并且是线程安全的。可以同时被多个线程访问。
2.1 顺序容器——QList类(掌握)
本节课程内容使用QList类存储Student元素,Student是自定义C++类型,在Qt项目中创建个C++的类。
- 在Qt Creator中选中项目名称,鼠标右键,点击添加新文件。
- 在弹出的窗口中,按照下图所示进行操作。
- 在弹出的窗口中输入类名(大驼峰/帕斯卡命名法)
- 在项目管理界面中点击”完成“。可以看到新的文件在项目中存在了。
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);
// 删除元素
lis.removeFirst(); // 删除第一个
lis.removeLast(); // 删除最后一个
lis.removeAt(1); // 删除第二个元素
// lis.removeAll(s2); // 删除所有相同的元素
// lis.removeOne(s4); // 删除所有相同元素的第一个
// 遍历
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() ;
}
// Java迭代器
// QListIterator<T> // 只读迭代器
// QMutableListIterator // 读写迭代器
// 创建一个Java迭代器对象,参数为容器对象
QListIterator<Student> iter(lis);
while(iter.hasNext()) // 判断当前迭代器指针后面是否有可用元素
{
Student s = iter.next(); // 向后移动当前迭代器,并取出元素
qDebug() << s.getId() << s.getName() << s.getMajor() ;
}
}
Dialog::~Dialog()
{
delete ui;
}
2.2 关联容器——QMap类(掌握)
重新实现了STL中std::map类,QMap也兼容map类的API,也增加一些新的Qt的API。
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("冠芝","美容美发");
map.insert("宵宾","电气焊");
map.insert("极强","要饭");
map.insert("昌平","捡破烂");
map.insert("华子哥","抽华子");
// 如果容器中的元素支持qDebug输出,则容器本身也支持输出。
qDebug () << map;
// 删除键值对
// 返回值为删除的键值对数量
qDebug() << map.remove("张三");
qDebug() << map.remove("张三");
// 判断某个键值对在不在
qDebug() << map.contains("张三"); // false
qDebug() << map.contains("冠芝"); // true
if(map.contains("华子哥"))
{
map["华子哥"] = "抽电子烟";
}
qDebug () << map;
qDebug() << map.value("张三","没有没有");
qDebug() << map.value("极强","没有没有");
// STL 迭代器遍历 C++
for(QMap<QString,QString>::iterator iter = map.begin();
iter != map.end(); iter++)
{
// 输出键与值
qDebug() << iter.key() << iter.value();
}
// java 迭代器
QMapIterator<QString,QString> iter(map);
while(iter.hasNext())
{
iter.next();
qDebug() << iter.key() << iter.value() ;
}
}
Dialog::~Dialog()
{
delete ui;
}
3、Qt数据类型(熟悉)
3.1 跨平台数据类型
Qt是一个跨平台的开发框架,所以必须要保证各个平台的数据类型长度保持一致,因此Qt对常见数据类型进行了新的定义符号。
在Qt环境下,可以直接使用。
3.2 QVariant 统一变量类
QVariant类型可以与Qt常见的类型完成相互转换,因此此类型的函数具有类似于多态的性质。
qint64 a = 123;
QVariant v(a);
QString str = v.toString(); // 转换成字符串
qDebug() << str ; // 字符串123
v = str;
int b = v.toInt(); // 转换成int
qDebug() << b; // 整型:123
4、时间与日期处理(掌握)
Qt中用QDate类处理日期,使用QTime类处理时间,使用QDateTime处理时间和日期。已QDateTime进行讲解。
需要注意的是,QDateTime的数据来自系统日期和时间,修改时间会影响到QDateTime的数据。
常用函数:
// 返回1970年1月1日00:00:00到现在的毫秒数
qint64 QDateTime::currentMSecsSinceEpoch()[static]
1、时间戳作用,计算代码的运行时间
- 时间戳的其他作用。
可以使用时间戳作为随机数的种子,但是需要注意,我们计算机的随机数都是伪随机。不是真正的随机数。计算机中无法做到真正的随机数。
获取当前的日期和时间对象
// 返回一个包含当前日期和时间的QDateTime对象
QDateTime QDateTime::currentDateTime()
秒:ss
// 拿到当前日期和时间的对象后,可以提取当前的日期和时间
// 格式化输出年月日,时分秒
QString QDateTime::toString(const QString & format) const
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;
}
其他的日期和时间的相关ui组件:
5、定时器类QTimer(掌握)
QTimer类可以实现一个延时任务,周期任务。
QTimer的常用属性有:
- active : const bool
当前定时器的运行状态
- interval : int
时间间隔,单位毫秒。
- singleShot : bool
表示当前当前定时器,是否是一次性的。
QTimer类的常用函数
// 构造函数 堆区开辟
QTimer::QTimer(QObject * parent = 0)
QLCDNumber组件
使用这个组件,显示出11:56:24 这样子的效果。
//QLCDNumber 的显示槽函数
void display(const QString & s)[slot]
// 定时器触发信号,时间到了就发送该信号
void QTimer::timeout()[signal]
// 启动定时器
void QTimer::start()[slot]
// 停止计时器
void QTimer::stop()[slot]
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
timeOutSlot(); // 提前刷新显示控件
// ui->lcdNumber->display("12:00:00");
timer = new QTimer(this);
// 设置定时器参数
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);
}