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_OBJECTpublic: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(); // 转换成intqDebug() << 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_OBJECTpublic:
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_OBJECTpublic: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);
}