在Qt5的这部分教程中,将讨论Qt5中的容器。将提到以下容器:QVector, QList, QStringList, QSet和QMap。
容器是在内存中存储指定类型项目的通用类。C++有标准模板库(STL),它有其自己的容器。在Qt中,我们可以使用Qt容器或者STL容器。
有两类容器:顺序和关系。顺序容器一个接着一个存储项目,而关系容器存储键值对。QList,QVector,QLinkedList属于顺序容器;QMap和QHash是关系容器的示例。
由于在本章中,我们创建了命令行程序,我们不需要Qt GUI模块。我们可以添加Qt -= gui声明到项目文件。
Qt5 QVector
QVector是一个模板类,它提供了一个动态数组。它在相邻内存位置存储它的项目并且提供快速基于索引的访问。对于大型矢量,插入操作更慢而推荐使用QList容器替代。
/*
本例使用整数向量。
*/
# include <QVector>
# include <QTextStream>
int main()
{
QTextStream out(stdout);
// 创建一个整数向量。
QVector<int> vals = {1,2,3,4,5,6};
// size方法给出了这个向量的尺寸--在此向量中的项目数。
out << "The size of the vector is: " << vals.size() << endl;
// first方法获取向量中第一项
out << "The first item is: " << vals.first() << endl;
// last方法获取向量中最后一项
out << "The last item is: " << vals.last() << endl;
// append方法在向量末尾插入值。
vals.append(7);
// prepend方法在向量头插入值。
vals.prepend(0);
// 循环遍历整个向量并且打印其内容
out << "Elements:";
for (int val : vals){
out << val << " ";
}
out << endl;
return 0;
}
程序执行结果如下:
[blctrl@localhost build-containers-Desktop-Debug]$ ./containers
The size of the vector is: 6
The first item is: 1
The last item is: 6
Elements:0 1 2 3 4 5 6 7
Qt5 QList
QList是一个用于创建一个元素列表的容器。它类似于QVector。它存储一个值的列表,并且提供快速的基于索引的访问,以及快速插入和移除。它是在Qt中最常用的容器之一。
/* 本例展示了QList容器 */
void testQList(QTextStream &out)
{
// 创建一个QList容器。并且存储了城市名称。
QList<QString> cities = {"Shanghai", "Beijing", "Tianjing", "Chongqing"};
out << "======================================================" <<endl;
// for循环遍历这个容器并且打印元素。at方法返回指定索引的项目。
for (int i = 0; i < cities.size(); i++){
out << cities.at(i) << endl;
}
// <<操作符用于插入两个项目到这个列表
cities << "Hangzhou" << "Shenzheng";
out << "*********************" << endl;
// std::sort方法按升序排序这个列表。
std::sort(cities.begin(), cities.end());
out << "Sorted:" << endl;
// 现在打印排序后的列表
for (QString city: cities){
out << city << endl;
}
out << "======================================================" <<endl;
}
以上程序调用结果如下:
======================================================
Shanghai
Beijing
Tianjing
Chongqing
*********************
Sorted:
Beijing
Chongqing
Hangzhou
Shanghai
Shenzheng
Tianjing
======================================================
Qt5 QStringList
QStringList是一个提供字符串列表的快捷容器。它有快速的基于索引的访问以及快速插入和移除。
/* 在这个示例中,我们从一个字符串创建了一个字符串列表并且打印元素到console */
void testQStringList(QTextStream &out)
{
QString strings = "coin, book, cup, pencil, clock, bookmark";
// QString的split方法根据提供的分隔符把字符串切成子串。在一个列表中返回这些子串。
QStringList items = strings.split(",");
// QStringListIterator提供了Java风格用于QStringList的const迭代器。
QStringListIterator it(items);
out << "********************************************************" <<endl;
// 用创建好的迭代器,我们打印这个列表的元素到终端。trimmed方法删除字符串元素中的空白。
while (it.hasNext()){
out << it.next().trimmed() << endl;
}
out << "======================================================" <<endl;
}
以上代码运行结果:
======================================================
coin
book
cup
pencil
clock
bookmark
======================================================
Qt5 QSet
QSet提供了一个可以快速查找的单值数学集合。不按顺序存储这些值。
/* 在本例中,QSet用于存储颜色, 它使得指定一种颜色多次没有意义 */
void testQSet(QTextStream &out)
{
// 创建颜色值的两个集合。在两个集合中都有蓝色。
QSet<QString> cols1 = {"yellow", "red", "blue"};
QSet<QString> cols2 = {"blue", "pink", "orange"};
out << "======================================================" <<endl;
// size方法返回这个集合的尺寸。
out << "There are " << cols1.size() << " values in the set" << endl;
// 用insert方法添加一个新颜色到一个集合
cols1.insert("brown");
out << "There are " << cols1.size() << " values in the set" << endl;
// unite方法执行两个集合的并集。cols1集合将从cols2中插入本集合中没有出现的项目到本集合
// 在本例中,除了蓝色外,cols2中的颜色都被插入到cols1中。
cols1.unite(cols2);
out << "There are " << cols1.size() << " values in the set" << endl;
// 我们用for循环打印了cols1结合中所有项目
for (QString val : cols1){
out << val << endl;
}
out << "************************************************************" << endl;
// 不支持set的排序。我们可以从set创建一个list并且对其排序。
// values方法返回一个新的QList,其包含这个set中的所有元素。
// 在QList中的元素顺序未被定义。
QList<QString> lcols = cols1.values();
std::sort(lcols.begin(), lcols.end());
for (QString val : lcols){
out << val << endl;
}
out << "======================================================" <<endl;
}
执行以上程序的结果:
======================================================
There are 3 values in the set
There are 4 values in the set
There are 6 values in the set
yellow
red
pink
brown
orange
blue
************************************************************
blue
brown
orange
pink
red
yellow
======================================================
Qt5 QMap
QMap是一个关系数组(字典),它存储键值对。它提供了用键查找关联值的快速查找。
/* 在本例中,我们创建了一个字典,我们在这个字典中映射字符串键到整数值 */
void testQMap(QTextStream &out)
{
out << "======================================================" <<endl;
// 创建一个QMap。它有两个键值对。
QMap<QString, int> items = {{"coins", 5},{"books", 3}};
// 用insert方法插入一个新对。
items.insert("bottles", 7);
// 获取这个字典的所有值,并且打印它们到console。values方法返回一个map值列表。
QList<int> values = items.values();
out << "Values: " << endl;
for (int val : values){
out << val << endl;
}
out << "*****************************************************" << endl;
// 同样,我们打印这个字典的所有键。keys方法返回包含这个字典中所有键的列表。
QList<QString> keys = items.keys();
for (QString key: keys){
out << key << endl;
}
out << "*****************************************************" << endl;
// QMapIterator是一个用于QMap的java风格迭代器。它可以用于迭代一个map的元素。
QMapIterator<QString, int>it(items);
out << "Pairs: " << endl;
// 在迭代器帮助下,我们遍历这个map的所有元素。key方法方法当前的键,而value方法返回当前值。
while (it.hasNext()){
it.next();
out << "key: " << it.key() << " value:" << it.value() << endl;
}
out << "======================================================" <<endl;
}
运行以上代码,结果如下:
======================================================
Values:
3
7
5
*****************************************************
books
bottles
coins
*****************************************************
Pairs:
key: books value:3
key: bottles value:7
key: coins value:5
======================================================
自定义类排序
/* 在以下示例中,我们在QList中排序一个自定义类的对象 */
//book.h 这是自定义Book类的头文件
#ifndef BOOK_H
#define BOOK_H
#include <QString>
class Book
{
public:
Book(QString, QString);
QString getAuthor() const;
QString getTitle() const;
private:
QString author;
QString title;
};
#endif // BOOK_H
/* book.cpp 这是Book类的实现,有两个访问方法 */
#include "book.h"
#include <QString>
Book::Book(QString auth, QString tit)
{
author = auth;
title = tit;
}
QString Book::getAuthor() const
{
return author;
}
QString Book::getTitle() const
{
return title;
}
/* main.cpp 主程序:本例中,创建了一些book对象,并且用std::sort算法对它们排序 */
#include "book.h"
bool compareByTitle(const Book &b1, const Book &b2) {
return b1.getTitle() < b2.getTitle();
}
void testCustomSort(QTextStream &out)
{
QList<Book> books = {
Book("Jack London", "The Call of the Wild"),
Book("Honoré de Balzac", "Father Goriot"),
Book("Leo Tolstoy", "War and Peace"),
Book("Gustave Flaubert", "Sentimental education"),
Book("Guy de Maupassant", "Une vie"),
Book("William Shakespeare", "Hamlet")
};
// 排序算法使用了排序函数compareByTitle
std::sort(books.begin(), books.end(), compareByTitle);
for (Book book : books){
out << book.getAuthor() << " : " << book.getTitle() << endl;
}
}
运行上程序,结果按作者名字降序排列,如下:
Honoré de Balzac : Father Goriot
William Shakespeare : Hamlet
Gustave Flaubert : Sentimental education
Jack London : The Call of the Wild
Guy de Maupassant : Une vie
Leo Tolstoy : War and Peace