Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не 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() не заменяет значение ключа, если ключ уже существует, а добавляет новую пару ключ-значение. |