|
Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не Qt, Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.
|
Структура проекта. Основные типы
12.5 Контейнерные классы в Qt
Список строк QStringList, который мы рассматривали, является представителем семейства контейнерных классов Qt, которые являются аналогом контейнеров STL. Но в то же время они имеют свои собственные различия в реализации и возможностях. Мы же будем в дальнейшем использовать в наших примерах исключительно контейнеры Qt.
Простейшим контейнерным классом является QList. QList — список общего назначения. Для добавления элементов в начало и в конец списка используют методы prepend() и append(). Также можно добавить несколько элементов за раз используя потоковые операторы. Например:
#include <QList>
...
QList<QString> lList;
QString lStr1 ( " string 1 " );
QString lStr2 ( " string 2 " );
lList << lStr1 << lStr2; //Добавляем несколько элементов за раз
lList.prepend ( lStr1 ); //Добавляем элемент в начало (повторно)
lList.append ( " string 3 " ); //Добавляем в конец списка
lList << " string 4 "; //То же, что и lList.append (" string 4 ");Последние две строки возможны за счёт неявного преобразования char* в QString. Класс QStringList, которого мы коснулись в примерах предыдущего раздела посвящённого текстовым строкам, наследует от QList<QString> и реализует ряд дополнительных методов для работы со строками в списке.
Для доступа к элементам используют метод at(), который принимает индекс элемента в списке в качестве аргумента. Количество элементов в списке возвращают методы size() и count().
qDebug ( ) << lList.first ( ); qDebug ( ) << lList.last ( ); if ( lList.size ( ) >3) qDebug ( ) << lList.at ( 3 );
Также стоит отметить два других важных разновидности контейнеров: хэш (QHash) и словарь (QMap). Хэш — контейнер, в котором элементы добавляют парами (ключ-значение). Значение в хэше находят по ключу, а для поиска используют хэш-функцию, которая преобразует ключ в значение. В словаре элементы также добавляют парами ключ-значение, но значение сортируют по ключу. Для доступа к значению, используют метод value(), который принимает два параметра: ключ и значение по умолчанию, которое метод вернёт, если значение не будет найдено. Например:
#include <QMap> ... QMap<QString, QString> lSurnameByName; lSurnameByName.insert ( " Bill ", " Hunter " ); lSurnameByName.insert ( " Marry ", " Lee " ); //Поиск значения по ключу qDebug ( ) << " Bill " << lSurnameByName.value ( " Bill " ); qDebug ( ) << " Marry " << lSurnameByName.value ( " Marry ", " Doe " ); //Прибавляем другое значение с уже существующим ключом lSurnameByName.insert ( " Marry ", " Hunter " ); qDebug ( ) << " Marry " << lSurnameByName.value ( " Marry " ); //Ключи не существуют — вывод значений по умолчанию qDebug ( ) << " James " << lSurnameByName.value ( " James " ); qDebug ( ) << " John " << lSurnameByName.value ( " John ", " Doe " );
После выполнения получим вывод:
Bill "Hunter" Marry "Lee" Marry "Hunter" James "" John "Doe"
Обратите внимание: после того, как мы добавили ещё одно значение с тем же ключом (Marry), предыдущее значение было перезаписано новым значением. Для того, чтобы добавить несколько значений с одним и тем же ключом можно воспользоваться методом insertMulti().
#include <QHash> ... QHash<QString, QString> lClassificationHash; //Добавляем несколько значений с одинаковыми ключами lClassificationHash.insertMulti ( " fruits ", " apple " ); lClassificationHash.insertMulti ( " fruits ", " orange " ); lClassificationHash.insertMulti ( " vegetables ", " potato " ); lClassificationHash.insertMulti ( " vegetables ", " cabbage " ); lClassificationHash.insertMulti ( " vegetables ", " tomato " ); qDebug ( )<< lClassificationHash.value ( " fruits " ); //Вывод одного значения с ключом qDebug ( )<< lClassificationHash.values ( " fruits " ); //Вывод значений с ключом qDebug ( )<< lClassificationHash.values ( " vegetables " );
Получим следующий вывод в консоль:
"orange"
("orange", "apple")
("tomato", "cabbage", "potato")Для итерации по списку можно воспользоваться макросом foreach. Также можно воспользоваться итератором в стиле Java. Например:
QList<int> lList; //Создаём список целых чисел
lList.append ( 3 ); //Добавляем элементы
lList.append ( 6 );
lList.append ( 9 );
QListIterator <int> lIt ( lList ); //Создаём итератор для списка
while ( lIt.hasNext ( ) ) //Пока следующий элемент существует
{
qDebug ( ) << lIt.next ( ); //...вывести следующий элемент
}Другой пример — итерация в обратном направлении. На этот раз используем хеш.
QHash<QString, int> lNumberByName;
lNumberByName.insert ( " twelve ", 12 );
lNumberByName.insert ( " thirty three ", 33 );
lNumberByName.insert ( " one hundred an twenty five ", 125 );
QHash It erator<QString, int> lHashIterator ( lNumberByName );
lHashIterator.toBack ( ); //Перейти к концу контейнера — итератор указывает после
//последнего элемента
while ( lHashIterator.hasPrevious ( ) )
{
lHashIterator.previous ( ); //Переходим к предыдущемму элементу
//Выводим ключ и значение
qDebug ( ) << lHashIterator.key ( )<< " - " << lHashIterator.value ( );
}Следующий пример — с итератором в стиле STL.
QHash<QString, int >::const_iterator lStlLikeIterator;
for ( lStlLikeIterator = lNumberByName.begin ( );
lStlLikeIterator != lNumberByName.end ( );
lStlLikeIterator ++)
{
qDebug ( ) << lStlLikeIterator.key ( )<< " - "
//Тоже самое, что и * lStlLikeIterator
<< lStlLikeIterator.value ( );
}| Переменная | Описание особенностей |
|---|---|
| QList | Список общего назначения для использования в большинстве ситуаций, которые возникают при разработке. Имеет оптимальное быстродействие в большинстве случаев. |
| QLinkedList | Реализует связный список в Qt. Отсутствует операция доступа по индексу элемента (такая как at(int pos)). |
| QVector | Реализует вектор элементов в Qt. |
| QStack | Реализует стек. Стек размещает элементы по принципу LIFO (Last In, First Out) — элемент, добавленный первым будет последним элементом в стеке. |
| QQueue | Реализует очередь. Очередь размещает элементы по принципу FIFO (First In, First Out) — элемент, добавленный первым, будет первым элементом в очереди |
| QSet | Множество элементов. Гарантирует, что все элементы будут уникальными. |
| QMap | Контейнерный класс для словаря. Элементы добавляют парами: ключ-значение. Словарь всегда сортирует элементы по ключу. Позволяет найти элемент по ключу. |
| QMultiMap | Контейнерный класс словаря создан для удобной работы с тем, чтобы каждому ключу соответствовало несколько значений. Метод insert() не заменяет значение ключа, если ключ уже существует, а добавляет новую пару ключ-значение. |
| QHash | Контейнерный класс для хеша. Элементы добавляют парами: ключ — значение. Элементы хранятся в хеше в произвольном порядке. Позволяет выполнять очень быстрый поиск элемента по ключу. |
| QMultiHash | Контейнерный класс хеша, создан для удобной работы с тем, чтобы каждому ключу соответствовало несколько значений. Метод insert() не заменяет значение ключа, если ключ уже существует, а добавляет новую пару ключ-значение. |