Qt学习总结(C鱼)之QList和QMap容器类

QList<T>

QList<T>容器是一个数组列表,特点如下:

1.大多数情况下可以用QList。像prepend()、append()和insert()这种操作,通常QList比QVector快的多。这是因为QList是基于index标签存储它的元素项在内存中(虽然内存不连续,这点与STL的list 是一样的),比那种依赖iterator迭代的容器类更快捷,而且你的代码也更少。

2.当迭代器指向QList中的一个项目后,如果QList进行了插入或者删除操作,那么这个迭代器就无效了。

3.QStringList类就是继承QList<QString>容器类(注意QList<QString>其实是一个类模板,里面装的是QString类型,然后又有一个QStringList类继承于它)。

QList<T>容器的简单用法(由于QStringList是继承于QList<String>,所以下面的所有用法对于QStringList容器一样适用):

#include <QCoreApplication>
#include<QList>
#include<QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QList<QString> list;//创建了一个QList容器,容器内部存储QString类型的数据,返回一个list对象,该对象有很多操作该容器的方法。
    list<<"aa"<<"bb"<<"cc";//可以采用<<的符号将数据输入到容器内存储。
    if(list[1]=="bb")
    {
        list[1]="ab";
    }
    list.replace(2,"bc");//list对象的replace方法将指定索引位置的元素值替换成指定的类型值,参数1是list索引位置,参数2是指定替换的类型值。
    qDebug()<<"the list is:";
    for(int i=0;i<list.size();++i)//list对象的size方法返回该容器存储的元素个数。
    {
        qDebug()<<list.at(i);//list对象的at方法访问容器内指定索引位置的元素值。
    }
    list.append("dd");//调用list对象的append函数进行尾插入指定类型值。
    list.prepend("mm");//调用list对象的prepend函数进行头插入指定类型值。
    QString str=list.takeAt(2);//调用list对象的takeAt函数删除指定索引值的元素并弹出该删除的类型值。
    qDebug()<<"at(2) item is:"<<str;
    qDebug()<<"the list is:";
    for(int i=0;i<list.size();++i)//list对象的size方法返回该容器存储的元素个数。
    {
        qDebug()<<list.at(i);//list对象的at方法访问容器内指定索引位置的元素值。
    }
    list.insert(2,"mm");//调用list对象的insert方法在指定索引位置插入指定的类型值,参数1是索引值,参数2是要插入的类型值。
    list.swap(1,3);//调用list对象的swap方法交换指定两个索引位置的元素值。
    qDebug()<<"the list is:";
    for(int i=0;i<list.size();++i)//list对象的size方法返回该容器存储的元素个数。
    {
        qDebug()<<list.at(i);//list对象的at方法访问容器内指定索引位置的元素值。
    }
    qDebug()<<"contains‘mm‘?"<<list.contains("mm");//判断列表中是否包含“mm”
    qDebug()<<"the ‘mm‘ count:"<<list.count("mm");//容器内包含“mm”的个数
    //第一个‘mm‘的位置,默认从0索引位置开始查找,找到就返回第一个匹配到的元素的索引位置
    qDebug()<<"the first ‘mm‘ index:"<<list.indexOf("mm");
    //第二个‘mm‘的位置,我们指定从索引位置1开始查找
    qDebug()<<"the second ‘mm‘ index:"<<list.indexOf("mm",1);
    return a.exec();
}

QMap<Key,T>

QMap<Key,T>容器是一个字典,属于关联容器的一种,特点如下:

1.它将Key类型的键值映射到T类型的值上,一般每个键关联一个值,特殊情况出现于调用insertMulti函数插入多值。

2.并且它是根据键顺序来存储它的顺序的。所以,QMap强调顺序,那么如果你存储的数据不关心存储顺序,可以考虑使用QHash来代替它。

QMap<Key,T>容器的简单用法():

#include <QCoreApplication>
#include<QMap>
#include<QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QMap<QString,int> map;//创建了一个QMap容器,容器内存储的键是QString类型,值是int类型,一个键只对应一个值,并且存储是讲究键顺序的。
    map["one"]=1;//当给一个容器内不存在的键赋值时,会自动将键和值添加进容器内
    map["three"]=3;
    map.insert("seven",7);//也可以使用insert来为容器添加键值对。

    int value1=map["six"];//当采用键索引的方式访问键的值时,若容器内无该键,那么就会自动插入该新键,并且值默认设为0。
    qDebug()<<"value1:"<<value1;
    qDebug()<<"contains‘six‘?"<<map.contains("six");

    int value2=map.value("five");//调用value函数,若指定要访问的键在容器内找不到,那么不会自动插入该新键,并且默认返回0,函数的参数2可以指定返回的值。
    qDebug()<<"value2:"<<value2;
    qDebug()<<"contains‘five‘?"<<map.contains("five");

    int value3=map.value("nine",9);//函数的参数2指定返回的值。
    qDebug()<<"value3:"<<value3;

    //map默认是一个键只对应存在一个值,所以,如果重新给该键设置了值,那么以前的值就会被删除替换,只保留最新的值。
    map.insert("ten",10);
    map.insert("ten",100);
    qDebug()<<"ten:"<<map.value("ten");

    /*
    map可以调用insertMulti函数来实现一键多值,值得注意的是,在QMap容器中,若存在某个键拥有多个值,那么调用平常的value和
    使用map[键名]索引的方式访问元素,那么实际上返回的就是调用insertMulti函数最后一次添加的值,而values函数是专门提供给
    一键多值的元素用来返回这个元素的所有存在的值形成的列表,这个列表可以使用QList来保存起来。
    */
    map.insertMulti("two",2);
    map.insertMulti("two",4);
    QList<int> values=map.values("two");
    qDebug()<<"two:"<<values;

    //上面是QMap容器对象调用insertMulti函数实现一键多值,其实有专门的容器类实现一键多值的操作和存储,例如:QMultimap
    //注意,这个QMultimap生成的一键多值对象和insertMulti函数实现的一键多值是有区别的,QMultimap对象不能够索引方式访问,但可以使用value函数来访问多值中最新的那个值,还有values函数可以返回该键对应的所有值列表。
    QMultiMap<QString,int> map1,map2,map3;
    map1.insert("values",1);//插入values键,指定第一个值为1
    map1.insert("values",2);//再次为values键插入第二个值为2
    map1.insert("qwe",888);//后面插入操作以此类推
    map1.insert("qwe",999);
    map2.insert("values",3);
    map2.insert("rty",444);

    map3=map1+map2;//相当于把map1对象内存储的values和qwe键(不管键对应多值还是单值),还有map2对象存储的values和rty键相合并然后全部放入到map3容器中。
    QList<int> myValues=map3.values("values");//QMultiMap容器类对象也跟QMap一样拥有values函数来返回指定键的所有值的列表
    qDebug()<<"the values are:";
    for(int i=0;i<myValues.size();++i)
    {
        qDebug()<<myValues.at(i);
    }
    return a.exec();
}

遍历容器(使用迭代器)

Qt容器类提供了两种风格的迭代器,分别是JAVA风格迭代器和STL风格迭代器。JAVA风格迭代器有两种数据类型,分别是只读迭代器和读/写迭代器。下面分别讲解QList和QMap两种容器类型的两种迭代器。

QList容器的两种迭代器

例如:

QList(容器类)->QListIterator(只读迭代器)->QMutableListIterator(读/写迭代器)

QListIterator(注意,JAVA风格迭代器一直指向项目之间,不是直接指向项目)常用API:

  1. toFront():将迭代器移动到List列表的最前面(第一个项目之前)。
  2. toBack():将迭代器移动到List列表的最后面(最后一个项目之后)。
  3. hasNext():检查该迭代器后面是否还有项目。
  4. next():迭代器向后移动,,返回它所跳过的项目。
  5. peekNext():迭代器不移动,返回它本来能跳过的项目。
  6. hasPrevious():检查迭代器前面是否还有项目。
  7. previous:迭代器向前移动,返回它所跳过的项目。
  8. peekPrevious():迭代器不移动,返回它本来能跳过的项目。

上面的API,QMutableListIterator迭代器也都有,但由于QListIterator是只读迭代器,所以没有提供插入和删除项目的函数,而QMutableListIterator容器提供了insert和setValue函数来插入、设置值,remove函数来删除项目。还有要注意的是QMutableListIterator容器虽然也有next和precious函数,但是与QListIterator迭代器有所不同,前者的这两个函数返回的是非const引用,说明可以作为左值进行赋值操作,而后者的两个函数返回的是const引用,说明不能用来赋值操作,只能用于读取,很符合这个只读迭代器的定义。下面给出QMutableListIterator迭代器三个操作项目的函数用法:

insert(value):在迭代器指向的位置插入一个项目。

setValue(value):这个函数是将指定项目的值设置成指定的值,所以必须有个前提就是前面执行过next或者previous函数,其实意思就是这个函数对上一次跳过的项目进行赋值。

remove():删除上一次跳过的项目。

案例代码如下:

#include <QCoreApplication>
#include<QDebug>
#include<QList>
#include<QListIterator>
#include<QMutableListIterator>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QList<QString> list;//创建了一个QList容器对象
    list<<"A"<<"B"<<"C"<<"D";
    QListIterator<QString> i(list);//创建了一个指向QList的只读迭代器,用list对象作为参数
    qDebug()<<"the forward is:";
    while(i.hasNext())
        qDebug()<<i.next();
    qDebug()<<"the backward is:";
    while(i.hasPrevious())
        qDebug()<<i.previous();

    QMutableListIterator<QString> j(list);//创建了一个读/写迭代器
    j.toBack();
    while(j.hasPrevious()){
        QString str = j.previous();
        if(str=="B") j.remove();
    }
    /*
    要十分注意上面这个while循环,其实原本是ABCD列表(假如从左到右排列),然后删除B后,因为最后又多执行了一次循环内部代码,所以迭代器就指向A的左侧了。
    */
    j.insert("Q");
    j.toBack();
    if(j.hasPrevious()) j.previous()="N";
    j.previous();
    j.setValue("M");
    j.toFront();
    qDebug()<<"the forward is:";
    while(j.hasNext())
        qDebug()<<j.next();
    return a.exec();
}

QMap容器的两种迭代器

例如:

QMap(容器类)->QMapIterator(只读迭代器)->QMutableMapIterator(读/写迭代器)

与QListIterator迭代器类似,QMapIterator迭代器也提供了toFront()、toBack()、hasNext()、next()、peekNext()、hasPrevious()、previous()和peekPrevious()等函数。我们知道next()、peekNext()、previous()和peekPrevious()可以遍历容器的内容,但仔细想想,前面QList还好,只有一个值,容易理解直接遍历取值就行,但是QMap可是字典,含有键值对,那么该怎样遍历获取键和值呢?next()、peekNext()、previous()和peekPrevious()这四个函数不再返回引用,而是直接返回项目对象。可以在返回的这个项目对象上分别使用key()和value()函数来获取键和值,也可以使用QMapIterator对象的key()和value()函数获取键和值,下面会有案例说明两者获取方法的不同。
代码如下:

#include <QCoreApplication>
#include<QDebug>
#include<QList>
#include<QListIterator>
#include<QMutableListIterator>
#include<QMap>
#include<QMapIterator>
#include<QMutableMapIterator>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QMap<QString,QString> map;
    map.insert("Paris","France");
    map.insert("Guatemala City","Guatemala");
    map.insert("Mexico City","Mexio");
    map.insert("Moscow","Russia");
    QMapIterator<QString,QString> i(map);//创建了一个只读迭代器指向QMap对象
    while(i.hasNext()){
        i.next();
        /*
        注意,调用next函数后返回的是一个项目对象,可以使用这个项目对象的key()和value()方法获取,
        例如:i.next().key()。但是对于这里的需求是我们需要获取键和值,如果连续两次执行i.next().key()
        和i.next().value()那么迭代器就移动两次了,很明显不符合我们的需求。其实当单独执行了这个函数,迭代器也向后移
        动了一次,并且内部已经保存了跳过的
        项目的键和值,它告诉我们可以通过i对象的key()和
        value()函数获取。就好像下面那条语句一样。
        */
        qDebug()<<i.key()<<":"<<i.value();
    }
    qDebug()<<"--------------------";
    if(i.findPrevious("Mexico")) qDebug()<<"find ‘Mexico‘";
    QMutableMapIterator<QString,QString> j(map);
    while(j.hasNext()){
        //下面的j.next.key()语句可以看出,就是我们上面介绍的那样,不过这里的应用场景是为了只单独获取键,然后匹配以City的项目后再删除。
        if(j.next().key().endsWith("City"))
            j.remove();
    }
    while(j.hasPrevious()){
        j.previous();
        qDebug()<<j.key()<<":"<<j.value();
    }
    return a.exec();
}

原文地址:http://blog.51cto.com/12731497/2170133

时间: 2024-09-29 22:57:59

Qt学习总结(C鱼)之QList和QMap容器类的相关文章

Qt学习(14)

Qt学习(14)——使用QByteArray 本节学习 QByteArray 的两种用法,第一种作为字符串处理类,类似 QString ,但 QByteArray内部字符编码不确定,所以要慎用.第二种是作为纯的字节数组,里面可以包含多个 '\0' ,经常用于网络数据的接收和发送. 1 QByteArray和char Qt最常用的字符串类是内码固定的QString,而针对传统类似C语言char*的字符串,Qt提供了QByteArray类来处理.QString的字符单元是QChar,QByteArr

qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果

应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm 先看看执行效果,我用的群创7寸屏,主机是mini2440,分辨率是800*480,程序写比較粗糙,但对刚開始学习的人还是有一点启示,大家一起进步. qt中提供了QGphicsView,QGraphicsScene,QGraphicsItem,QGraphicsPixmapItem是QGraphicsItem的子类 分辨创建它们的实

Qt 学习

Qt 学习 C++ 模版 QObject 提供一个十分有用的 api,T findChild(QString, Qt::FindChildOptions),这个函数接收一个模版参数,返回模版参数的类型(如果子对象可以造型成 T ),也就是说返回值已经做了 cast 造型处理,这样就可以直接用特定的子类指针接收,使用起来非常方便.可以在对象的子类中寻找特定名称(objectName)的对象,而 Qt::FindChildOptions 参数用于设置搜索范围,Qt::FindDirectChildr

Qt学习之路

  Qt学习之路_14(简易音乐播放器) Qt学习之路_13(简易俄罗斯方块) Qt学习之路_12(简易数据管理系统) Qt学习之路_11(简易多文档编辑器) Qt学习之路_10(Qt中statusBar,MessageBox和Timer的简单处理) Qt学习之路_9(Qt中Item Widget初步探索) Qt学习之路_8(Qt中与文件目录相关操作) Qt学习之路_7(线性布局和网格布局初步探索) Qt学习之路_6(Qt局域网聊天软件) Qt学习之路_5(Qt TCP的初步使用) Qt学习之路

QT学习之路(1):彩票绝对不中模拟器

//============================================//绝对不中,彩票开奖模拟器#include "mainwindow.h"#include "ui_mainwindow.h"#include <QHash>#include <QDebug>MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::M

qt学习(三):鼠标图标改变

qt学习 (三):鼠标图标改变 当你进入一个美好的qt软件场景,比如游戏,电脑的黑白图标会让程序逊色不少, 1改图标要加光标的头文件, 2 载入光标图, 3 再设置改光标就可以了 1在头文件中加 #include <QtGui>  //光标类的父类 //再在public成员中声明换的函数void keyPressEvent(QKeyEvent *k); //声明按键换图的函数         .h文件    --注意头文件和声明 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Qt学习总结-ui篇(二)

qccs定义圆角 border-radius:10px; 如果想给特定位置定义圆角,如: 左上角:border-left-top-radius:10px; 右下角色:border-right-bottom-rasius:10px; 半透明效果 只需要在css中使用rgba(100,100,100,40)这种形式来表示颜色即可. 为可执行文件添加图标 1.新建文件:finename.rc 文件名无所谓,只要后缀为rc就可以. 2.编辑新建的文件,输入以下内容: IDI_ICON1 ICON DIS

【qt学习005】搞不明白的布局

记录一下自己在布局这一章遇见的各种狗屎问题. 问题主要出现在布局最后一节:综合布局实例,类似于一个qq管理器的界面(见下图1).看见这个时,打算动手实现一下,于是开始写代码,写着写着发现不知道怎么写了,遇见一些无法解决的问题(问题中描述的布局类之间的关系见下图2): 1. 最底层应该使用哪一类? 2. 怎么将QListWidget加入到最底层? 3. 怎么往QStackWidget加入三个页面,每个页面代表不同的信息? 4. 怎么将QHBoxLayout中的CLOSE按钮连接到退出函数,要完整地

【Qt学习笔记】13.拖放技术:Drag & Drop

1.接受拖放 Drag & Drop 是一个界面操作,用于在两个窗口间传递数据. Drag Source: 拖放源窗口 Drag Target: 拖放目标窗口 拖放操作: 1.在源窗口:选中目标,按下鼠标,移动,拖至目标窗口(Drag) 2.在目标窗口:取消鼠标,到指定位置,松开鼠标(Drop) (按下ESC取消操作) MIME: MIME(Multipurpose Internet Mail Extensions)被传递的数据以MIME格式传送,它是多组type-data数据:(type0,