返回介绍

Containers in Qt5

发布于 2025-02-22 22:19:28 字数 14077 浏览 0 评论 0 收藏 0

In this part of the Qt5 tutorial, we will talk about containers in Qt5. The following containers are mentioned: QVector , QList , QStringList , QSet , and QMap .

Containers are general-purpose classes that store items of a given type in memory. C++ has the Standard Template Library (STL), which has its own containers. It Qt, we can use Qt containers or STL containers.

There are two kinds of containers: sequential and associative. Sequential containers store items one after another, whereas associative containers store key-value pairs. QList , QVector , QLinkedList belong to sequential containers; QMap and QHash are examples of associative containers.

QVector

QVector is a template class that provides a dynamic array. It stores its items in adjacent memory locations and provides fast index-based access. For large vectors, inserting operations are slower and QList container is recommended instead.

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;
}

The example works with a vector of integers.

QVector<int> vals = {1, 2, 3, 4, 5};

A vector of integers is created.

out << "The size of the vector is: " << vals.size() << endl;

The size() method gives the size of the vector—the number of items in the vector.

out << "The first item is: " << vals.first() << endl;

The first item is retrieved with the first() method.

out << "The last item is: " << vals.last() << endl;

The last item of the vector is found with the last() method.

vals.append(6);

The append() method inserts the value at the end of the vector.

vals.prepend(0);

The prepend() method inserts the value at the beginning of the vector.

for (int val : vals) {
  out << val << " ";
}  

We go through the vector in the for loop and print its contents.

Output

$ ./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 is a container for creating a list of elements. It is similar to QVector . It stores a list of values and provides fast index-based access as well as fast insertions and removals. It is one of the most commonly used containers in 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;
  }  
}

The example presents the QList container.

QList<QString> authors = {"Balzac", "Tolstoy", 
  "Gulbranssen", "London"};

A QList container is created. It stores the names of writers.

for (int i=0; i < authors.size(); ++i) {

  out << authors.at(i) << endl;
}  

In a for loop, we go through the container and print its elements. The at() method returns the item at the given index.

authors << "Galsworthy" << "Sienkiewicz";

The << operator is used to insert two new items into the list.

std::sort(authors.begin(), authors.end());

The std::sort() method sorts the list in ascending order.

out << "Sorted:" << endl;
for (QString author : authors) {

  out << author << endl;
} 

Now we print the sorted list.

Output

$ ./mylist 
Balzac
Tolstoy
Gulbranssen
London
***********************
Sorted:
Balzac
Galsworthy
Gulbranssen
London
Sienkiewicz
Tolstoy

QStringList

QStringList is a convenience container that provides a list of strings. It has fast index-based access as well as fast insertions and removals.

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;  
  }
}

In the example, we create a list of strings from a string and print the elements into the console.

QString string = "coin, book, cup, pencil, clock, bookmark";
QStringList items = string.split(",");

The QString's split() method cuts the string into substrings according to the provided separator. The substrings are returned in a list.

QStringListIterator it(items);

QStringListIterator provides a Java-style const iterator for QStringList .

while (it.hasNext()) {
  out << it.next().trimmed() << endl;  
}

With the created iterator, we print the elements of the list to the terminal. The trimmed() method trims the white space in the string element.

Output

$ ./mystringlist 
coin
book
cup
pencil
clock
bookmark

QSet

QSet provides a single-valued mathematical set with fast lookups. The values are stored in an unspecified order.

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;
}

The QSet is used to store colours in the example. It makes no sense to have one colour value specified more times.

QSet<QString> cols1 = {"yellow", "red", "blue"};
QSet<QString> cols2 = {"blue", "pink", "orange"};

We have two sets of colour values. Blue colour is located in both sets.

out << "There are " << cols1.size() << " values in the set" << endl;

The size() method returns the size of the set.

cols1.insert("brown");

We add a new value to a set with the insert() method.

cols1.unite(cols2);

The unite(( method performs a union of two sets. The cols1 set will have all items inserted from cols2 set that are not already present; in our case, all except for the colour blue.

for (QString val : cols1) {
  out << val << endl;
}

With the for loop, we print all the items in the cols1 set.

QList<QString> lcols = cols1.values();
std::sort(lcols.begin(), lcols.end());

Sorting of a set is not supported. We can create a list out of a set and sort it. The values() method returns a new QList containing the elements in the set. The order of the elements in the QList is undefined.

Output

$ ./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 is an associative array (dictionary) that stores key-value pairs. It provides fast lookup of the value associated with a key.

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;  
  }
}

In the example, we have a dictionary where we map string keys to integer values.

QMap<QString, int> items = { {"coins", 5}, {"books", 3} };

A QMap is created. It has two pairs.

items.insert("bottles", 7);

A new pair is inserted with the insert() method.

QList<int> values = items.values();

out << "Values:" << endl;

for (int val : values) {
  out << val << endl;
}

We get all the values of the dictionary and print them to the console. The values() method returns a list of map values.

QList<QString> keys = items.keys();

out << "Keys:" << endl;
for (QString key : keys) {
  out << key << endl;
} 

Likewise, we print all the keys of the dictionary. The keys() method returns a list containing all the keys in the dictionary.

QMapIterator<QString, int> it(items);

QMapIterator is a Java-style iterator for a QMap . It can be used to iterate over elements of a map.

while (it.hasNext()) {
  it.next();
  out << it.key() << ": " << it.value() << endl;  
}

With the help of the iterator, we walk over all elements of the map. The key() method returns the current key and the value() method returns the current value.

Output

$ ./myqmap 
Values:
3
7
5
Keys:
books
bottles
coins
Pairs:
books: 3
bottles: 7
coins: 5

Custom class sorting

In the following example, we are going to sort objects of a custom class in a QList .

book.h

class Book {
  
  public:
    Book(QString, QString);
    QString getAuthor() const;
    QString getTitle() const;
    
  private:      
    QString author;
    QString title;  
};

This is the header file for our custom Book class.

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;
}

This is the implementation of the Book class; we have two accessor methods.

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;
  }
}

In the example, we create a few book objects and sort them with the std::sort algorithm.

bool compareByTitle(const Book &b1, const Book &b2) {
  
  return b1.getTitle() < b2.getTitle();
}

The compareByTitle() is a comparison function used by the sort algorithm.

std::sort(books.begin(), books.end(), compareByTitle);

The std::sort algorithm sorts the books in the list by the book's title.

Output

$ ./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

In this chapter, we have worked with Qt's containers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文