学习QT之容器类
Qt提供了一组通用的基于模板的容器类。对比C++的标准模板库中的容器类,Qt的这些容器更轻量、更安全并且更容易使用。此外,Qt的容器类在速度、内存消耗和内联(inline)代码等方面进行了优化(较少的内联代码将说件可执行程序的大小)。
存储在Qt容器中的数据必须是可赋值的数据类型,也就是说,这种数据类型必须提供一个默认的构造函数、一个复制构造函数和一个赋值操作运算符。
这样的数据类型包含了通常使用的大多数数据类型,包括基本数据类型(如int和double等)和Qt的一些数据类型(如QString、QDate和QTime等)。不过,Qt的QObject及其他的子类(如QWidget和QDialog等)是不能存储在容器中的,例如:QList list;,一个可代替的方案是存储QObject及其子类的指针,例如:QList<QToolBar *> list。容器也可以嵌套使用,例如:QHash<QString,QList >; 注意容器类嵌套时后面的>
之间一定要加一个空格,否则,C++编译器会将两个>
符号解释为>>
,导致无法通过编译器编译。
一、QList类、QLinkedList类和QVector类
1、QList类
QList是迄今为止最常用的容器类,它存储给定数据类型T的一列数值。继承自QList类的子类有QItemSelection、QQueue、QSigbalSpy、QStringList和QTestEventList。
函数 | 功能 |
---|---|
append() | 在尾部追加数据 |
prepend() | 在头部追加数据 |
insert(pos, value) | 在pos位置处插入value |
#include<QDebug>
int main()
{
QList<QString> list; //初始化一个QList<QString>对象list
{
QString str("This is a string");
list<<str; //将字符串str加入list中
}
qDebug()<<list[0]<<"How are you! ";
return 0;
}
2、QLinkedList类
QLinkedList是一个链式列表,它以非连续的内存块保存数据。
QLinkedList不能使用下标,只能使用迭代器访问它的数据项。与QList相比,当对一个很大的列表进行插入操作时,QLinkedList具有更高的效率。
3、QVector类
QVector在相邻的内存中存储给定数据类型T的一组数值。在一个QVector的前部或者中间位置进行插入操作的速度是很慢的,这因为这样的操作将导致内存中的大量数据被移动,这是由QVector存储数据的方式决定的。
QVector既可以使用下标访问数据项,也可以使用迭代器访问数据项。继承自QVector类的子类有QPolygon、QPolygonF和QStack。
4、java风格迭代器遍历容器
Java风格迭代器同STL风格迭代器相比,使用起来更简单方便,不过这也是以轻微的性能损耗为代价的。对于每一个容器类,Qt提供了两种类的Java风格迭代器数据类型,即只读迭代器类和读写迭代器类。
容器类 | 只读迭代器类 | 读写迭代器类 |
---|---|---|
QList,QQueue | QListIterator | QMutableListIterator |
QLinkedList | QLinkedListIterator | QMutableLinkedListIterator |
QVector,QStack | QVectorIterator | QMutableVectorIterator |
Java风格迭代器的迭代的位于列表项的中间,而不是直接指向某个列表项。因此,它的迭代点或者在第一个列表项的前面,或者在两个列表项之间,或者在最后一个列表项之后。
(1)、QList只读迭代器遍历
方法 | 功能 |
---|---|
hasNext() | 检查当前迭代点之后是否有列表项 |
hasPrevious() | 检查当前迭代点之前是否有列表项 |
toBack() | 将迭代点移到最后一个列表项的后面 |
toFront() | 将迭代点移动列表的最前端 |
next() | 跳过下一个列表项,并返回它跳过的列表项的内容 |
peekNext() | 返回下一个列表项,但不移动迭代点 |
peekPrevious() | 返回前一个列表项,但不移动迭代点 |
findNext() | 从当前迭代点开始向后查找指定的列表项,如果找到,则返回true,此时迭代点位于匹配列表项的后面;如果没有找到,则返回false,此时迭代点位于列表项的后端(最后一个列表项的后面) |
findPrevious() | 与findNext()类似,不同的是,它的方向是向前的,查找操作完成后的迭代点在匹配项的前面或整个列表的前端 |
实例代码;
#include<QCoreApplication>
#include<QDebug>
int main(int argc,char *argv[])
{
QCoreApplication a(argc,argv);
QList<int> list; //创建一个空的列表list
QListIterator<int> iter(list); //创建一个上述列表的只读迭代器
list<<1<<2<<3<<4;
for(;iter.hasNext();)
qDebug()<<iter.next();
return a.exec();
}
(2)、QList读写迭代器遍历
读写迭代器除了上述基本的遍历操作外,还提供了如下函数:
方法 | 功能 |
---|---|
insert(value) | 在列表中插入值value |
remove() | 在列表中移除数据 |
setValue(value) | 在列表中设置数据 |
实例代码;
#include<QCoreApplication>
#include<QDebug>
int main(int argc,char *argv[])
{
QCoreApplication a(argc,argv);
QList<int> list; //创建一个空的列表list
QMutableListIterator<int> iter(list); //创建一个上述列表的只读迭代器
for(int i=0;i<10;i++)
iter.insert(i);
for(i.toFront;i.hasNext();)
qDebug()<<iter.next();
for(iter.toBack();iter.hasPrevious;)
{
if(iter.previous()%2==0)
iter.remove();
else
iter.setValue(iter.peekNext()*10);
}
for(iter.toFront();iter.hasNext();)
qDebug()<<iter.next();
return a.exec();
}
5、STL风格迭代器遍历容器
对于每个容器类,Qt都提供了两种类型的STL风格迭代器数据类型:一种提供只读访问;另一种提供读写访问。由于只读类型的迭代器的运行速度要比读写迭代器的运行速度快,所以应尽可能地使用只读类型的迭代器。
STL风格迭代器的API是建立在指针操作基础上的。例如,“++”操作运算符移动迭代器到下一个项(item),而"*"操作运算符返回迭代器指向的项。
不同于Java风格迭代器,STL风格迭代器的迭代点直接指向列表项
容器类 | 只读迭代器 | 读写迭代器 |
---|---|---|
QList,QQueue | QList::const_iterator | QList::iterator |
QLinkedList | QLinkedList::const_iterator | QLinkedList::iterator |
QVector,QStack | QVector::const_iterator | QVector::iterator |
#include<QCoreApplication>
#include<QDebug>
int main(int argc,char *argv[])
{
QCoreApplication a(argc,argv);
QList<int> list;
QList<int>::iterator iter; //创建一个读写迭代器
for(int i=0;i<10;i++)
list.insert(list.end(),i);
for(iter=list.begin();iter!=list.end();++iter)
{
qDebug()<<*iter;
*iter=(*iter)*10;
}
QList<int>::const_iterator c_iter; //创建一个只读迭代器
for(c_iter=list.constBegin();c_iter!=list.constEnd();++c_iter)
qDebug()<<*c_iter;
return a.exec();
}
QLinkedList和QVector具有和QList相同的遍历接口,在此就不再详细讲解了。
二、QMap类和QHash类
QMap类和QHash类具有非常类似的功能,它们的差别仅在于:
- QHash具有比QMap更快的查找速度;
- QHash以任意的顺序存储数据项,而QMap总是按照键key的顺序存储数据;
- QHash的键类型key必须提供operator==()和一个全局的qHash(Key)函数,而QMap的键类型Key必须提供opeator<()函数。
1、QMap类
QMap<Key,Value>提供了一个从类型为Key的键到类型为T的值的映射。通常QMap存储的数据形式是一个键对应一个值,并且按照键Key的顺序存储数据。为了能够支持一键多值的情况,QMap提供了QMap<Key,Value>::insertMulti()和QMap<Key,Value>::values()函数。存储一键多值的数据时,也可以使用QMultiMap<Key,Value>容器,它继承自QMap。
2、QHash类
QHash<Key,Value>具有和QMap几乎完全相同的API。QHash维护着一张哈希表,哈希表的大小与QHash的数据项的数目相适应。
QHash以任意顺序组织它的数据。当存储数据的顺序无关紧要是,建议使用QHash作为存放数据的容器。QHash也可以存储一键多值形式的数据,它的子类QMultiHash<Key,Value>实现了一键多值的语言。
3、Java风格迭代器遍历
对于每一个容器,Qt都提供了两种类型的Java风格迭代器数据类型:一种提供只读访问;另一种提供读写访问。
容器类 | 只读迭代器类 | 读写迭代器类 |
---|---|---|
QMap<Key,Value>,QMultiMap<Key,Value> | QMapIterator<Key,Value> | QMutableMapIterator<Key,Value> |
QHash<Key,Value>,QMultiHash<Key,Value> | QHashIterator<Key,Value> | QMutableHashIterator<Key,Value> |
(1)、QMap只读迭代器遍历
方法 | 功能 |
---|---|
hasNext() | 检查是否有下一个列表项 |
next() | 跳过下一个列表项,并访问该列表项 |
key() | 访问键 |
value() | 访问值 |
findValue(value) | 寻找值 |
setValue(value) | 设置值 |
insert(Key,Value) | 插入键值对 |
#Include<QCoreApplication>
#Include<QDebug>
int main(int argc,char *argv)
{
QCoreApplication a(argc,argv);
QMap<QString,QString> map;
map.insert("BeiJin","111");
map.insert("ShangHai","021");
map.insert("NanJin","025");
QMapIterator<QString,QString> const_iter(map);
for(;const_iter.hasNext();)
{
const_iter.next;
qDebug()<<" "<<const_iter.key()<<" "<<const_iter.value();
}
QMutableMapIterator<QString,QString> iter(map);
if(iter.findNext("111"))
iter.setValue("101");
for(;iter.hasNext();)
{
iter.next();
qDebug()<<" "<<iter.key()<<" "iter.value();
}
return a.exec();
}
运行结果如下:
"BeiJin" "111"
"NanJin" "025"
"ShangHai" "021"
"BeiJin" "101"
"NanJin" "025"
"ShangHai" "021"
4、STL风格迭代器遍历
对于每一个容器类,Qt都提供了两种类型的STL风格迭代器数据类型:一种提供只读访问;另一种提供读写访问。
容器类 | 只读迭代器类 | 读写迭代器类 |
---|---|---|
QMap<Key,Value>,QMultiMap<Key,Value> | QMap<Key,Value>::const_iterator | QMap<Key,Value>::iterator |
QHash<Key,Value>,QMultiHash<Key,Value> | QHash<Key,Value>::const_iterator | QHash<Key,Value>::iterator |
#include<QCoreApplication>
#Include<QDebug>
int main(int argc,char *argv)
{
QCoreApplication a(argc,argv);
QMap<QString,QString> map;
map.insert("BeiJin","111");
map.insert("ShangHai","021");
map.insert("NanJin","025");
QMap<QString,QString>::const_iterator const_iter;
for(const_iter=map.constBegin();const_iter!=map.constEnd();++const_iter)
qDebug()<<" "<<const_iter.key()<<" "<<const_iter.value();
QMap<QString,QString>::iterator iter;
iter=map.find("BeiJin");
if(iter!=map.end())
iter.value()="010";
QMap<QString,QString>::const_iterator modi;
for(modi=map.constBegin();modi!=map.constEnd();++modi)
qDebug()<<" "<<modi.key()<<" "modi.value();
return a.exec();
}
运行结果如下:
"BeiJin" "111"
"NanJin" "025"
"ShangHai" "021"
"BeiJin" "101"
"NanJin" "025"
"ShangHai" "021"
三、QVariant类
QVariant类类似于C++的联合(union)数据类型,它不仅能保存很多Qt类型的值,包括QCore、QBrush、QFont、QPen、QString和QSize等,而且也能存放Qt的容器类型的值。Qt的很多功能都是建立在QVariant基础上的,如Qt的对象属性即数据库功能等。
#include"widget.h"
#include<QDebug>
#include<QVariant>
#include<QColor>
Widget::Wideget(QWidget *parent)
: QWidget(parent)
{
QVariant v(709); //声明一个QVariant变量,并初始化为一个整数
qDebug()<<v.toInt();
QVariant w("How are you! "); //声明一个QVariant变量,并初始化为一个字符串
qDebug()<<w.toString;
QMap<QString,QVariant> map;
map["int"]=709;
map["double"]=709.709;
map["string"]="How are you! ";
map["color"]=QColor(255,0,0);
qDebug()<<map["int"]<<map["int"].toInt();
qDebug()<<map["double"]<<map["double"].toDouble();
qDebug()<<map["string"]<<map["string"].toString();
qDebug()<<map["color"]<<map["color"].value<QColor>();
QStringList s1;
s1<<"A"<<"B"<<"C"<<"D";
QVariant slv(s1);
if(slv.type==QVariant.toStringList)
{
QStringList list=slv.toStringList();
for(int i=0;i<list.size();++i)
qDebug()<<list.at(i);
}
}
说明:QVariant::type()函数返回存储在QVariant变量中的值的数据类型。QVariant::StringList是Qt定义的一个QVariant::type枚举类型的变量。Qt的常用QVariant::type枚举类型变量如下:
变量 | 对应的类型 | 变量 | 对应的类型 |
---|---|---|---|
QVariant::Invaild | 无效类型 | QVariant::Time | QTime |
QVariant::Region | QRegion | QVariant::Line | QLine |
QVariant::Bitmap | QBitmap | QVariant::Palette | QPalette |
QVariant::Bool | bool | QVariant::List | QList |
QVariant::Brush | QBrush | QVariant::SizePolicy | QSizePolicy |
QVariant::Size | QSize | QVariant::String | QString |
QVariant::Char | QChar | QVariant::Map | QMap |
QVariant::Color | QColor | QVariant::StringList | QStringList |
QVariant::Cursor | QCursor | QVariant::Point | QPoint |
QVariant::Date | QDate | QVariant::Pen | QPen |
QVariant::DateTime | QDateTime | QVariant::Pixmap | QPixmap |
QVariant::Double | double | QVariant::Rect | QRect |
QVariant::Font | QFont | QVariant::Image | QInage |
QVariant::Icon | QIcon | QVariant::UserType | 用户自定义类型 |
运行结果如下:
709
"How are you! "
QVariant(int 709) 709
QVariant(double,709.709) 709.709
QVariant(QString,"How are you! ") "How are you! "
QVariant(QColor,QColor(ARGB 1,1,0,0)) QColor(ARGB 1,1,0,0)
"A"
"B"
"C"
"D"
来源:CSDN
作者:贝勒里恩
链接:https://blog.csdn.net/Mr_robot_strange/article/details/104588788