在 Qt5 教程的这一部分中,我们将讨论 Qt5 中的容器。 提及以下容器:QVector
,QList
,QStringList
,QSet
和QMap
。
容器是通用类,用于将给定类型的项目存储在内存中。 C++ 具有标准模板库(STL),该模板库具有自己的容器。 对于 Qt,我们可以使用 Qt 容器或 STL 容器。
有两种容器:顺序容器和关联容器。 顺序容器一个接一个地存储项目,而关联容器存储键值对。 QList
,QVector
,QLinkedList
属于顺序容器; QMap
和QHash
是关联容器的示例。
QVector
QVector
是提供动态数组的模板类。 它将项目存储在相邻的内存位置,并提供基于索引的快速访问。 对于大向量,插入操作较慢,建议改用QList
容器。
myvector.cpp
#include <QVector>
#include <QTextStream>
int main(void) {
QTextStream out(stdout);
QVector<int> vals = {1, 2, 3, 4, 5};
out << "The size of the vector is: " << vals.size() << endl;
out << "The first item is: " << vals.first() << endl;
out << "The last item is: " << vals.last() << endl;
vals.append(6);
vals.prepend(0);
out << "Elements: ";
for (int val : vals) {
out << val << " ";
}
out << endl;
return 0;
}
该示例使用整数向量。
QVector<int> vals = {1, 2, 3, 4, 5};
创建一个整数向量。
out << "The size of the vector is: " << vals.size() << endl;
size()
方法给出向量的大小-向量中的项数。
out << "The first item is: " << vals.first() << endl;
使用first()
方法检索第一项。
out << "The last item is: " << vals.last() << endl;
使用last()
方法可以找到向量的最后一项。
vals.append(6);
append()
方法将值插入向量的末尾。
vals.prepend(0);
prepend()
方法将值插入向量的开头。
for (int val : vals) {
out << val << " ";
}
我们遍历for
循环中的向量并打印其内容。
输出:
$ ./myvector
The size of the vector is: 5
The first item is: 1
The last item is: 5
Elements: 0 1 2 3 4 5 6
QList
QList
是用于创建元素列表的容器。 与QVector
相似。 它存储值列表,并提供基于索引的快速访问以及快速插入和删除。 它是 Qt 中最常用的容器之一。
mylist.cpp
#include <QTextStream>
#include <QList>
#include <algorithm>
int main(void) {
QTextStream out(stdout);
QList<QString> authors = {"Balzac", "Tolstoy",
"Gulbranssen", "London"};
for (int i=0; i < authors.size(); ++i) {
out << authors.at(i) << endl;
}
authors << "Galsworthy" << "Sienkiewicz";
out << "***********************" << endl;
std::sort(authors.begin(), authors.end());
out << "Sorted:" << endl;
for (QString author : authors) {
out << author << endl;
}
}
该示例介绍了QList
容器。
QList<QString> authors = {"Balzac", "Tolstoy",
"Gulbranssen", "London"};
创建一个QList
容器。 它存储作家的姓名。
for (int i=0; i < authors.size(); ++i) {
out << authors.at(i) << endl;
}
在for
循环中,我们遍历容器并打印其元素。 at()
方法返回给定索引处的项目。
authors << "Galsworthy" << "Sienkiewicz";
<<
运算符用于在列表中插入两个新项目。
std::sort(authors.begin(), authors.end());
std::sort()
方法按升序对列表进行排序。
out << "Sorted:" << endl;
for (QString author : authors) {
out << author << endl;
}
现在我们打印排序列表。
输出:
$ ./mylist
Balzac
Tolstoy
Gulbranssen
London
***********************
Sorted:
Balzac
Galsworthy
Gulbranssen
London
Sienkiewicz
Tolstoy
QStringList
QStringList
是提供字符串列表的便捷容器。 它具有基于索引的快速访问以及快速的插入和删除。
mystringlist.cpp
#include <QTextStream>
#include <QList>
int main(void) {
QTextStream out(stdout);
QString string = "coin, book, cup, pencil, clock, bookmark";
QStringList items = string.split(",");
QStringListIterator it(items);
while (it.hasNext()) {
out << it.next().trimmed() << endl;
}
}
在示例中,我们从一个字符串创建一个字符串列表,并将元素打印到控制台中。
QString string = "coin, book, cup, pencil, clock, bookmark";
QStringList items = string.split(",");
QString
的split()
方法根据提供的分隔符将字符串切成子字符串。 子字符串在列表中返回。
QStringListIterator it(items);
QStringListIterator
为QStringList
提供了 Java 样式的常迭代器。
while (it.hasNext()) {
out << it.next().trimmed() << endl;
}
使用创建的迭代器,我们将列表的元素打印到终端。 trimmed()
方法可修剪字符串元素中的空白。
输出:
$ ./mystringlist
coin
book
cup
pencil
clock
bookmark
QSet
QSet
提供具有快速查找功能的单值数学集。 值以未指定的顺序存储。
myset.cpp
#include <QSet>
#include <QList>
#include <QTextStream>
#include <algorithm>
int main(void) {
QTextStream out(stdout);
QSet<QString> cols1 = {"yellow", "red", "blue"};
QSet<QString> cols2 = {"blue", "pink", "orange"};
out << "There are " << cols1.size() << " values in the set" << endl;
cols1.insert("brown");
out << "There are " << cols1.size() << " values in the set" << endl;
cols1.unite(cols2);
out << "There are " << cols1.size() << " values in the set" << endl;
for (QString val : cols1) {
out << val << endl;
}
QList<QString> lcols = cols1.values();
std::sort(lcols.begin(), lcols.end());
out << "*********************" << endl;
out << "Sorted:" << endl;
for (QString val : lcols) {
out << val << endl;
}
return 0;
}
在示例中,QSet
用于存储颜色。 多次指定一种颜色值没有意义。
QSet<QString> cols1 = {"yellow", "red", "blue"};
QSet<QString> cols2 = {"blue", "pink", "orange"};
我们有两组颜色值。 两组中都有蓝色。
out << "There are " << cols1.size() << " values in the set" << endl;
size()
方法返回集合的大小。
cols1.insert("brown");
我们使用insert()
方法向集合中添加新值。
cols1.unite(cols2);
unite((
方法执行两个集合的并集。 cols1
设置将具有从cols2
设置插入的所有尚不存在的项目。 在我们的案例中,除了蓝色以外的所有颜色。
for (QString val : cols1) {
out << val << endl;
}
使用for
循环,我们打印cols1
集中的所有项目。
QList<QString> lcols = cols1.values();
std::sort(lcols.begin(), lcols.end());
不支持对集合进行排序。 我们可以创建一个列表并对其进行排序。 values()
方法返回一个新的QList
,其中包含集合中的元素。 QList
中元素的顺序未定义。
输出:
$ ./myset
There are 3 values in the set
There are 4 values in the set
There are 6 values in the set
pink
orange
brown
blue
yellow
red
*********************
Sorted:
blue
brown
orange
pink
red
yellow
QMap
QMap
是一个存储键值对的关联数组(字典)。 它提供与键关联的值的快速查找。
myqmap.cpp
#include <QTextStream>
#include <QMap>
int main(void) {
QTextStream out(stdout);
QMap<QString, int> items = { {"coins", 5}, {"books", 3} };
items.insert("bottles", 7);
QList<int> values = items.values();
out << "Values:" << endl;
for (int val : values) {
out << val << endl;
}
QList<QString> keys = items.keys();
out << "Keys:" << endl;
for (QString key : keys) {
out << key << endl;
}
QMapIterator<QString, int> it(items);
out << "Pairs:" << endl;
while (it.hasNext()) {
it.next();
out << it.key() << ": " << it.value() << endl;
}
}
在示例中,我们有一个字典,在其中将字符串键映射到整数值。
QMap<QString, int> items = { {"coins", 5}, {"books", 3} };
创建了QMap
。 它有两对。
items.insert("bottles", 7);
使用insert()
方法插入一对新的对。
QList<int> values = items.values();
out << "Values:" << endl;
for (int val : values) {
out << val << endl;
}
我们获取字典的所有值并将其打印到控制台。 values()
方法返回映射值列表。
QList<QString> keys = items.keys();
out << "Keys:" << endl;
for (QString key : keys) {
out << key << endl;
}
同样,我们打印字典的所有键。 keys()
方法返回一个列表,其中包含字典中的所有键。
QMapIterator<QString, int> it(items);
QMapIterator
是QMap
的 Java 样式的迭代器。 它可用于遍历映射元素。
while (it.hasNext()) {
it.next();
out << it.key() << ": " << it.value() << endl;
}
在迭代器的帮助下,我们遍历了映射的所有元素。 key()
方法返回当前键,value()
方法返回当前值。
输出:
$ ./myqmap
Values:
3
7
5
Keys:
books
bottles
coins
Pairs:
books: 3
bottles: 7
coins: 5
自定义类排序
在下面的示例中,我们将在QList
中对自定义类的对象进行排序。
book.h
class Book {
public:
Book(QString, QString);
QString getAuthor() const;
QString getTitle() const;
private:
QString author;
QString title;
};
这是我们的自定义Book
类的头文件。
book.cpp
#include <QString>
#include "book.h"
Book::Book(QString auth, QString tit) {
author = auth;
title = tit;
}
QString Book::getAuthor() const {
return author;
}
QString Book::getTitle() const {
return title;
}
这是Book
类的实现; 我们有两种访问器方法。
sortcustomclass.cpp
#include <QTextStream>
#include <QList>
#include <algorithm>
#include "book.h"
bool compareByTitle(const Book &b1, const Book &b2) {
return b1.getTitle() < b2.getTitle();
}
int main(void) {
QTextStream out(stdout);
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")
};
std::sort(books.begin(), books.end(), compareByTitle);
for (Book book : books) {
out << book.getAuthor() << ": " << book.getTitle() << endl;
}
}
在示例中,我们创建了一些书本对象,并使用std::sort
算法对其进行排序。
bool compareByTitle(const Book &b1, const Book &b2) {
return b1.getTitle() < b2.getTitle();
}
compareByTitle()
是排序算法使用的比较功能。
std::sort(books.begin(), books.end(), compareByTitle);
std::sort
算法按书名对列表中的书进行排序。
输出:
$ ./sortcustomclass
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
在本章中,我们使用了 Qt 的容器。