QVariant в Qt — универсальное хранилище любых типов данных

Автор: | 12 июня, 2025

QVariant — это универсальный контейнер из библиотеки Qt, предназначенный для хранения значения любого типа (в пределах поддерживаемых Qt). Он широко используется в моделях (QAbstractItemModel), при сериализации, работе с базой данных (QSqlQuery), взаимодействии с QML, и во многих других частях Qt-приложений.

Что такое QVariant

QVariant позволяет хранить значения разных типов, таких как int, double, QString, QDateTime, QMap, QVector, QList, QByteArray, и даже пользовательские типы (при регистрации).
Это аналог std::any или boost::any, но с интеграцией в экосистему Qt.

Пример:

QVariant value = 42;         // int
QVariant text = "Hello";     // QString
QVariant point = QPoint(5, 10); // QPoint

Преобразование типов

Чтение значений

QVariant v = 3.14;
double d = v.toDouble();   // 3.14

QVariant str = "123";
int i = str.toInt();       // 123

Проверка типа

if (v.typeId() == QMetaType::Double) {
    qDebug() << "Это double!";
}

Проверка на пустое значение

QVariant v;
if (!v.isValid()) {
    qDebug() << "Значение не задано";
}

Использование с QVariantList и QVariantMap

QVariantList list = {1, "two", 3.0};

for (const QVariant& item : list) {
    qDebug() << item;
}

QVariantMap map;
map["name"] = "Alice";
map["age"] = 30;

qDebug() << map["name"].toString();  // Alice
qDebug() << map["age"].toInt();      // 30

Использование с QModelIndex (в таблицах и списках)

QVariant MyModel::data(const QModelIndex& index, int role) const {
    if (role == Qt::DisplayRole) {
        return "Отображаемое значение";
    }
    return QVariant();
}

Поддержка пользовательских типов

struct MyData {
    int id;
    QString name;
};

Q_DECLARE_METATYPE(MyData)

// где-то в начале приложения
qRegisterMetaType<MyData>("MyData");

// теперь можно:
MyData d{1, "Example"};
QVariant v = QVariant::fromValue(d);
MyData extracted = v.value<MyData>();

Часто используемые методы

МетодНазначение
.toInt(), .toString() и т.д.Преобразование к нужному типу
.isValid()Проверка, содержит ли QVariant данные
.isNull()Проверка на null
.typeId()Получение ID типа (QMetaType::Type)
.canConvert<T>()Проверка, возможно ли преобразование
.convert(T)Преобразование к типу вручную
.typeName()Получение имени типа (const char*)

Важные особенности

  • QVariant копирует данные (не содержит ссылок).
  • Он не предназначен для хранения указателей на QObject* — используйте QPointer или QVariant::fromValue() с осторожностью.
  • Можно использовать QVariant как значение в QMap<QString, QVariant> — это позволяет удобно строить иерархические данные, например, JSON-подобные структуры.

Когда использовать QVariant

Используйте QVariant, если:

  • Вы пишете модель/вью в Qt (QTableView, QListView)
  • Вам нужно передавать данные между компонентами (особенно в QML)
  • Вы работаете с QSqlQuery или QSettings
  • Нужно временно хранить данные разных типов в одной структуре (QMap<QString, QVariant>)

QVariant — это фундаментальный инструмент в Qt, позволяющий гибко обращаться с различными типами данных, не зная их точного типа заранее. Он незаменим в model/view, сериализации, QML, базе данных и динамических структурах.