目录
1. 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 QString::number(int n, int base = 10)[static]
// int → QString
// 参数1 要转换的数字
// 参数2 进制
// 返回值 转换后的当前对象,支持链式调用
QString & setNum(int n, int base = 10)
// QString → int
// 参数1 转成功或失败
// 参数2 进制
// 返回值 转换后的int值,转换失败返回0
int QString::toInt(bool * ok = 0, int base = 10) const
不建议死记QString的API,因为数量较多而且都有实例代码,只需要把常用的关键字记住即可:
QString str = "你好あえㅔㅖ";
ui->label->setText(str);
// int → QString
int a = 255;
qDebug() << QString::number(a,16); // "ff"
qDebug() << QString::number(a,2); // "11111111"
qDebug() << str.setNum(a,8).append("!!!"); //"377!!!"
// QString → int
bool result = false;// 转换的结果
str = "0";
qDebug() << str.toInt(&result); // 0
qDebug() << result; // true
str = "uuu";
qDebug() << str.toInt(&result); // 0
qDebug() << result; // false
2. 容器类
Qt重写了C++的STL中的容器类,相比于C++ STL的容器类,Qt的容器类更轻巧、安全和易于使用,因为Qt的容器类进行了速度和存储优化,减少了可执行文件的生成体积,几乎全面兼容STL容器类API接口,并且是线程安全的,可以同时被多个线程访问。
2.1 顺序容器——QList类
本次课程内容实用QList类存储Student元素,Student是自定义C++类型,在Qt项目中创建一个C++类的操作步骤如下:
1. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件”.
2. 在弹出的窗口中,按照下图操作
3. 在弹出的窗口中输入类名
4. 在项目管理界面点击“完成”。可以看到新的文件在项目中存在了。
下面的例子使用QList来存储自定义类型Student。
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> class26011;
// 准备一些学生对象
Student s1("蔡徐坤",18,"唱跳rap篮球");
Student s2("周杰伦",38,"唱歌");
Student s3("韦朕",26,"PUBG");
Student s4("于小超",28,"STM32");
Student s5("Doinb",25,"MID");
Student s6("老孟",31,"bzr");
// 添加元素
class26011.append(s1);
class26011.push_back(s2); // 向后追加
class26011.prepend(s3); // 向前追加
class26011 << s4 << s5; // 连续追加
// 取出单个元素
//qDebug() << class26011[0].getName() << class26011.at(1).getName();
// 插入元素
// 参数1 插入的位置
// 参数2 插入的元素
class26011.insert(1,s6);
// STL迭代器
for(QList<Student>::const_iterator iter = class26011.begin();
iter != class26011.end();iter++)
{
Student s = *iter;
qDebug() << s.getName() << s.getAge() << s.getMajor();
}
qDebug() <<"_________________________________________";
// java 风格迭代器
// 只读:QListIterator
// 读写:QMutableListIterator
QListIterator<Student> iter(class26011);
while(iter.hasNext())
{
Student s = iter.next();// 向后移动迭代器指针取出元素对象
qDebug() << s.getName() << s.getAge() << s.getMajor();
}
QList<int> list;
list << 34 << 56 << 123 << 34 << 56;
list.removeAll(34); // 移除所有34
list.removeFirst(); // 移除第一个元素
list.removeLast(); // 移除最后一个元素
list<< 111 << 111 << 111;
list.removeOne(111); // 移除第一个111
list.removeAt(1); // 移除第二个元素
// 修改元素
// 参数1 修改的元素位置
// 参数2 新元素值
list.replace(0,666);
qDebug() << list;
}
Dialog::~Dialog()
{
delete ui;
}
2.2 关联容器——QMap类
重新实现了STL里中std::map类,QMap也兼容map类的API,也增加一些新的Qt API。
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QMap<QString,QString> map; // 创建一个栈内存的对象
// 插入数据
// 参数1 KEY
// 参数2 VALUE
map.insert("姓名","蔡徐坤");
map.insert("年龄","10坤岁");
map.insert("练习时长","1坤年");
map.insert("住址","北京海淀区");
map.insert("专业","rap");
// 如果容器中的元素类型支持qDebug输出,则容器本身也支持数量
qDebug() << map;
// 删除键值对
// 返回值为删除键值对数量
qDebug() << map.remove("练习时长"); // 1
qDebug() << map.remove("练习时长"); // 0
// 判断某个键在不在
qDebug() << map.contains("住址"); // true
qDebug() << map.contains("练习时长"); // false
if(map.contains("专业"))
map["专业"] = "唱跳";
qDebug() << map;
// 取出元素
// 参数1 key
// 参数2 取出VALUE失败时,输出参数2传入的默认值
qDebug() << map.value("年龄","empty"); //"10坤岁"
qDebug() << map.value("年龄2","empty"); //"empty"
// STL 迭代器
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()
{
delete ui;
}
3. Qt 的数据类型
3.1 跨平台数据类型
Qt是一个跨平台的开发框架,所以必须要保证各个平台的数据类型长度保持一致,因此Qt为常见的基本数据类型定义了类型符号:
3.2 QVariant 统一变量类型
QVariant类型可以与Qt常见的数据类型完成互相转换,因此此类型的函数具有类似于多态的性质。
可以使用QVariant类型完成数据类型的转换。
qint64 a = 1232334;
QVariant v(a);
QString text = v.toString();
qDebug() << text << endl << a;
3.3 QStringList 字符串列表
几乎相当于QList<QString>
需要引入头文件#include<QStringList>
QStringList s1;
s1 << "1uhsakudhuoad" << "oshuadu";
qDebug() << s1;
4. 时间与日期处理
Qt中用QDate类处理日期,使用QTime类处理时间,使用QDateTime类处理日期和时间,以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
t 当前时间和日期的标准市区
还有一些日期和时间相关的ui组件:
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;
private slots:
// 与翻页信号连接的槽函数
void pageSlot(int,int);
// 连接每次选择日子的信号的槽函数
void selectionSlot();
};
#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);
qint64 time = QDateTime::currentMSecsSinceEpoch();
qDebug() << time - start;
// 设置随机数种子
qsrand(time);
// 1-10 随机数
int rand = qrand() % 10 + 1;
qDebug() << rand;
// 获得一个基于当前时间和日期的对象
QDateTime dt = QDateTime::currentDateTime();
// 时间和日期格式化
qDebug() << dt.toString("yyyy-MM-dd hh:mm:ss t");
connect(ui->calendarWidget,SIGNAL(currentPageChanged(int,int)),
this,SLOT(pageSlot(int,int)));
connect(ui->calendarWidget,SIGNAL(selectionChanged()),
this,SLOT(selectionSlot()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::pageSlot(int y, int m)
{
qDebug() << "翻页了" << y << "年" << m << "月";
}
void Dialog::selectionSlot()
{
// 获取当前的日期
QDate date = ui->calendarWidget->selectedDate();
// 格式化
qDebug() << "选择了" << date.toString("dd") << "日";
}
5. QTimer 定时器类
使用LCD Number七段数码管显示当地时间。
最大显示数量
// QLcdNumber 的显示槽函数
void display(const QString & s)[slot]
QTimer类可以实现一个延时任务,或周期任务。
QTimer的常用属性有:
● interval : int
间隔时间,单位毫秒ms
● singleShot : bool
是否为一次性定时器
● active : const bool
当期定时器的运行状态
QTimer的常用函数
// 构造函数
QTimer::QTimer(QObject * parent = 0)
// 启动定时器,如果定时器已经在运行,则会重启
void QTimer::start(int msec)[slot]
// 定时器到点时发射的信号
void QTimer::timeout()[signal]
// 停止定时器运行
void QTimer::stop()[slot]
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QTimer>
#include <QDebug>
#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:
// 到点时,与timeout信号连接的槽函数
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);
// 设置是否为一次性
timer->setSingleShot(false);
// 设置触发时间1s
timer->setInterval(1000);
connect(timer,SIGNAL(timeout()),
this,SLOT(timeoutSlot()));
timer->start();
}
Dialog::~Dialog()
{
delete ui;
// 如果在运行先停止
if(timer->isActive())
timer->stop();
delete timer;
}
void Dialog::timeoutSlot()
{
// 到点了输出当地时间
QDateTime dt = QDateTime::currentDateTime();
// 时间格式化
QString text = dt.toString("hh:mm:ss");
ui->lcdNumber->display(text);
}