Читаем QT 4: программирование GUI на С++ полностью

Можно создавать произвольно сложные структуры данных, используя тип QVariant для обеспечения вложенных структур контейнеров:

QMap pearMap;

pearMap["Standard"] = 1.95;

pearMap["Organic"] = 2.25;

QMap fruitMap;

fruitMap["Orange"] = 2.10;

fruitMap["Pineapple"] = 3.85;

fruitMap["Pear"] = pearMap;

Здесь мы создали отображение со строковыми ключами (названия продукции) и значениями, которыми могут быть либо числа с плавающей точкой (цены), либо отображения. Отображение верхнего уровня содержит три ключа: «Orange», «Pear» и «Pineapple» (апельсин, груша и ананас). Значение, связанное с ключом «Реаг», является отображением, содержащим два ключа «Standard» и «Organic» (стандартный и экологически чистый). При проходе по ассоциативному массиву, содержащему объекты QVariant, нам необходимо использовать функцию type для проверки находящегося в QVariant типа, чтобы можно было его правильно обработать.

Способ создания подобным образом структур данных может быть очень привлекательным, поскольку мы можем создавать любые структуры данных. Но удобство применения типа QVariant достигается за счет снижения эффективности и читаемости программы. Для хранения наших данных, как правило, предпочтительнее использовать соответствующий класс языка С++ там, где это возможно.

QVariant используется мета-объектной системой Qt и поэтому является частью модуля QtCore. Тем не менее, когда мы собираем приложение с модулем QtGui, QVariant может хранить такие типы, связанные с графическим пользовательским интерфейсом, как QColor, QFont, QIcon, QImage или QPixmap:

QIcon icon("open.png");

QVariant variant = icon;

Для извлечения значений этих типов из QVariant мы можем следующим образом использовать шаблонную функцию—член QVariant::value:

QIcon icon = variant.value;

Функция value также может использоваться для преобразования между типами неграфического интерфейса и типом QVariant, однако на практике обычно используются функции преобразования вида to… (например, toString) для преобразования типов неграфического интерфейса.

QVariant может также использоваться для хранения пользовательских типов данных при условии обеспечения ими стандартного конструктора и конструктора копирования. Чтобы это заработало, прежде всего необходимо зарегистрировать тип, используя макрос Q_DECLARE_METATYPE обычно в заголовочном файле после определения класса:

Q_DECLARE_METATYPE(BusinessCard)

Это позволяет нам написать следующий программный код:

BusinessCard businessCard;

QVariant variant = QVariant::fromValue(businessCard);

if (variant.canConvert) {

BusinessCard card = variant.value;

}

Эти шаблонные функции—члены не будут работать с компилятором MSVC 6 из-за ограничений последнего. Если вы не можете отказаться от этого компилятора, вместо указанных функций используйте глобальные функции qVariantFromValue, qVariantValue и qVariantCanConvert.

Если в пользовательском типе данных предусмотрены операторы << и >> для записи и чтения из потока данных QDataStream, их можно зарегистрировать, используя функцию qRegisterMetaTypeStreamOperators. Это позволяет, среди прочего, хранить параметры настройки пользовательских типов данных, используя QSettings. Например:

qRegisterMetaTypeStreamOperators("BusinessCard");

В данной главе основное внимание было уделено контейнерам Qt, а также классам QString, QByteArray и QVariant. Кроме этих классов Qt имеет несколько других контейнеров. Один из них — QPair, который просто хранит два значения и аналогичен классу std::pair. Еще одним контейнером является QBitArray, который мы будем использовать в первом разделе главы 19. Наконец, имеется контейнер QVarLengthArray — низкоуровневая альтернатива вектору QVector. Поскольку он заранее выделяет память в стеке и не допускает неявное совместное использование, накладные расходы у него меньше, чем у вектора QVector, что делает его более подходящим в напряженных циклах.

Алгоритмы Qt, включая несколько не рассмотренных здесь, например qCopyBackward и qEqual, описаны в документации Qt, которую можно найти по адресуБолее подробное описание контейнеров Qt, в том числе информацию об их временных и объемных характеристиках, можно найти на странице http://doc.trolltech.com/4.1/containers.html.

<p>Глава 12. Ввод—вывод</p>
Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже