本系列博文旨在为 Qt 开发者提供一站式的学习资源,内容涵盖从基础控件使用到高级特性如多线程与图形编程等。如果你是第一次来到这里,可以先点击Qt 编程专栏简介,一起深入探索 Qt 的各个方面。
QVariant
是 Qt 提供的一个非常强大的类,它用于存储不同类型的数据,并支持多种类型之间的转换。QVariant
类被广泛应用于 Qt 的模型-视图框架、信号-槽机制、数据库操作、表格等场景中。它能将多种类型的数据封装到一个单一的对象中,并提供丰富的接口进行访问和类型转换。
功能 | 描述 |
---|---|
构造函数 | 支持从基本数据类型、QString 、QByteArray 、QDate 等多种类型初始化。 |
数据存储与访问 | 提供存储和访问不同类型数据的方法,如 toInt() ,toString() ,toBool() 等。 |
类型信息 | 提供获取当前存储数据类型的接口,如 type() ,canConvert() 等。 |
类型转换 | 支持数据类型的转换,可以通过 toType() 方法进行类型转换,支持 QVariant::toString() ,QVariant::toInt() 等。 |
比较操作 | 提供比较方法(如 == ,!= ,< ,> 等)来比较 QVariant 对象。 |
持久化与序列化 | 可以方便地与 Qt 的模型-视图框架、数据库进行交互,通过 QVariantMap 等数据结构进行存储和管理。 |
接口 | 功能描述 | 示例 |
---|---|---|
bool canConvert(QMetaType type) const |
判断当前 QVariant 对象是否能转换为指定的 QMetaType 类型。 |
QVariant v(42); bool canConvert = v.canConvert(QMetaType::fromType |
bool canConvert() const |
判断当前 QVariant 是否可转换为其自身类型。 |
QVariant v(42); bool canConvert = v.canConvert(); |
bool canView() const |
判断当前 QVariant 是否可以作为视图类型存在。 |
QVariant v(42); bool canView = v.canView(); |
void clear() |
清空 QVariant 中存储的数据。 |
QVariant v(42); v.clear(); |
const void *constData() const |
返回 QVariant 内部数据的常量指针。 |
QVariant v("Hello"); const void* data = v.constData(); |
bool convert(QMetaType targetType) |
将当前 QVariant 对象转换为目标类型。 |
QVariant v(42); bool success = v.convert(QMetaType::fromType |
void *data() |
返回 QVariant 内部数据的指针。 |
QVariant v("Hello"); void* data = v.data(); |
const void *data() const |
返回 QVariant 内部数据的常量指针。 |
QVariant v("Hello"); const void* data = v.data(); |
bool isNull() const |
判断 QVariant 是否为空(即没有有效数据)。 |
QVariant v; bool isNull = v.isNull(); |
bool isValid() const |
判断 QVariant 是否有效。 |
QVariant v(42); bool isValid = v.isValid(); |
QMetaType metaType() const |
获取当前 QVariant 对象的类型信息。 |
QVariant v(42); QMetaType type = v.metaType(); |
void setValue(T &&value) |
设置 QVariant 的值,支持右值引用。 |
QVariant v; v.setValue(42); |
void setValue(const QVariant &value) |
设置 QVariant 的值,支持拷贝。 |
QVariant v; v.setValue(QVariant(42)); |
void setValue(QVariant &&value) |
设置 QVariant 的值,支持右值引用赋值。 |
QVariant v; v.setValue(QVariant(42)); |
void swap(QVariant &other) |
交换当前 QVariant 对象与另一个 QVariant 的值。 |
QVariant v1(42), v2("Hello"); v1.swap(v2); |
QBitArray toBitArray() const |
将 QVariant 转换为 QBitArray 。 |
QVariant v(1); QBitArray arr = v.toBitArray(); |
bool toBool() const |
将 QVariant 转换为布尔值。 |
QVariant v(true); bool b = v.toBool(); |
QByteArray toByteArray() const |
将 QVariant 转换为 QByteArray 。 |
QVariant v("Hello"); QByteArray ba = v.toByteArray(); |
QChar toChar() const |
将 QVariant 转换为单一字符。 |
QVariant v("H"); QChar ch = v.toChar(); |
QDate toDate() const |
将 QVariant 转换为 QDate 。 |
QVariant v("2024-11-01"); QDate date = v.toDate(); |
QDateTime toDateTime() const |
将 QVariant 转换为 QDateTime 。 |
QVariant v("2024-11-01 12:00:00"); QDateTime dt = v.toDateTime(); |
double toDouble(bool *ok = nullptr) const |
将 QVariant 转换为 double ,并返回是否成功。 |
QVariant v(42.5); double d = v.toDouble(); |
QEasingCurve toEasingCurve() const |
将 QVariant 转换为 QEasingCurve 。 |
QVariant v(QEasingCurve::InOutQuad); QEasingCurve curve = v.toEasingCurve(); |
float toFloat(bool *ok = nullptr) const |
将 QVariant 转换为 float ,并返回是否成功。 |
QVariant v(42.5f); float f = v.toFloat(); |
QHash |
将 QVariant 转换为 QHash 。 |
QVariant v(QHash |
int toInt(bool *ok = nullptr) const |
将 QVariant 转换为 int ,并返回是否成功。 |
QVariant v(42); int i = v.toInt(); |
QJsonArray toJsonArray() const |
将 QVariant 转换为 QJsonArray 。 |
QVariant v(QJsonArray{1, 2, 3}); QJsonArray jsonArray = v.toJsonArray(); |
QJsonDocument toJsonDocument() const |
将 QVariant 转换为 QJsonDocument 。 |
QVariant v(QJsonDocument(QJsonObject{{"key", 42}})); QJsonDocument jsonDoc = v.toJsonDocument(); |
QJsonObject toJsonObject() const |
将 QVariant 转换为 QJsonObject 。 |
QVariant v(QJsonObject{{"key", 42}}); QJsonObject jsonObject = v.toJsonObject(); |
QJsonValue toJsonValue() const |
将 QVariant 转换为 QJsonValue 。 |
QVariant v(42); QJsonValue jsonValue = v.toJsonValue(); |
QLine toLine() const |
将 QVariant 转换为 QLine 。 |
QVariant v(QLine(0, 0, 10, 10)); QLine line = v.toLine(); |
QLineF toLineF() const |
将 QVariant 转换为 QLineF 。 |
QVariant v(QLineF(0, 0, 10.5, 10.5)); QLineF lineF = v.toLineF(); |
QList |
将 QVariant 转换为 QList 。 |
QVariant v(QList |
QLocale toLocale() const |
将 QVariant 转换为 QLocale 。 |
QVariant v(QLocale::English); QLocale locale = v.toLocale(); |
qlonglong toLongLong(bool *ok = nullptr) const |
将 QVariant 转换为 qlonglong ,并返回是否成功。 |
QVariant v(1234567890LL); qlonglong ll = v.toLongLong(); |
QMap |
将 QVariant 转换为 QMap 。 |
QVariant v(QMap |
QModelIndex toModelIndex() const |
将 QVariant 转换为 QModelIndex 。 |
QVariant v(QModelIndex()); QModelIndex modelIndex = v.toModelIndex(); |
QPersistentModelIndex toPersistentModelIndex() const |
将 QVariant 转换为 QPersistentModelIndex 。 |
QVariant v(QPersistentModelIndex()); QPersistentModelIndex persistentModelIndex = v.toPersistentModelIndex(); |
QPoint toPoint() const |
将 QVariant 转换为 QPoint 。 |
QVariant v(QPoint(10, 20)); QPoint point = v.toPoint(); |
QPointF toPointF() const |
将 QVariant 转换为 QPointF 。 |
QVariant v(QPointF(10.5, 20.5)); QPointF pointF = v.toPointF(); |
qreal toReal(bool *ok = nullptr) const |
将 QVariant 转换为 qreal ,并返回是否成功。 |
QVariant v(42.5); qreal real = v.toReal(); |
QRect toRect() const |
将 QVariant 转换为 QRect 。 |
QVariant v(QRect(0, 0, 10, 10)); QRect rect = v.toRect(); |
QRectF toRectF() const |
将 QVariant 转换为 QRectF 。 |
QVariant v(QRectF(0, 0, 10.5, 10.5)); QRectF rectF = v.toRectF(); |
QRegularExpression toRegularExpression() const |
将 QVariant 转换为 QRegularExpression 。 |
QVariant v(QRegularExpression("\\d+")); QRegularExpression regex = v.toRegularExpression(); |
QSize toSize() const |
将 QVariant 转换为 QSize 。 |
QVariant v(QSize(10, 20)); QSize size = v.toSize(); |
QSizeF toSizeF() const |
将 QVariant 转换为 QSizeF 。 |
QVariant v(QSizeF(10.5, 20.5)); QSizeF sizeF = v.toSizeF(); |
QString toString() const |
将 QVariant 转换为 QString 。 |
QVariant v("Hello"); QString str = v.toString(); |
QStringList toStringList() const |
将 QVariant 转换为 QStringList 。 |
QVariant v(QStringList{"Hello", "World"}); QStringList strList = v.toStringList(); |
QTime toTime() const |
将 QVariant 转换为 QTime 。 |
QVariant v("12:30:00"); QTime time = v.toTime(); |
uint toUInt(bool *ok = nullptr) const |
将 QVariant 转换为 uint ,并返回是否成功。 |
QVariant v(42); uint ui = v.toUInt(); |
qulonglong toULongLong(bool *ok = nullptr) const |
将 QVariant 转换为 qulonglong ,并返回是否成功。 |
QVariant v(1234567890ULL); qulonglong ull = v.toULongLong(); |
QUrl toUrl() const |
将 QVariant 转换为 QUrl 。 |
QVariant v(QUrl("https://www.qt.io")); QUrl url = v.toUrl(); |
QUuid toUuid() const |
将 QVariant 转换为 QUuid 。 |
QVariant v(QUuid::createUuid()); QUuid uuid = v.toUuid(); |
int typeId() const |
获取 QVariant 存储数据的类型ID。 |
QVariant v(42); int typeId = v.typeId(); |
const char *typeName() const |
获取 QVariant 存储数据的类型名称。 |
QVariant v(42); const char* typeName = v.typeName(); |
int userType() const |
获取用户自定义类型的 ID。 | QVariant v(QMetaType::fromType |
T value() const |
获取 QVariant 中存储的值,返回类型为 T 。 |
QVariant v(42); int value = v.value |
T view() |
返回对存储数据的视图,通常用于常量引用类型。 | QVariant v(42); int view = v.view |
以下是一个使用 QVariant
存储并转换不同数据类型的示例:
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 使用 QVariant 存储整数
QVariant var1 = 42;
qDebug() << "var1 (int):" << var1.toInt();
// 使用 QVariant 存储字符串
QVariant var2 = "Hello, QVariant!";
qDebug() << "var2 (QString):" << var2.toString();
// 转换 QVariant 存储的数据类型
QVariant var3 = 42.5;
qDebug() << "var3 (double):" << var3.toDouble();
// 判断是否可以转换类型
qDebug() << "Can var1 convert to QString?" << var1.canConvert(QMetaType::fromType<QString>());
// 使用 setValue 设置新的值
var3.setValue(100);
qDebug() << "After setValue, var3 (int):" << var3.toInt();
return a.exec();
}
QVariant
支持许多常见的数据类型,可以存储和转换以下类型的数据:
基础类型:int
,float
,double
,bool
,char
,long
,short
等。
Qt 类型:QString
,QDate
,QTime
,QDateTime
,QByteArray
,QColor
,QPoint
,QSize
,QRect
等。
STL 类型:std::string
,std::vector
等。
自定义类型:可以通过 Q_DECLARE_METATYPE
声明自定义类型以支持存储到 QVariant
中。
QVariant variant1 = 42; // 存储整数
QVariant variant2 = 3.14; // 存储浮点数
QVariant variant3 = "Hello"; // 存储字符串
int intValue = variant1.toInt(); // 将 QVariant 转换为 int 类型
double doubleValue = variant2.toDouble(); // 转换为 double 类型
QString stringValue = variant3.toString(); // 转换为 QString 类型
qDebug() << intValue << doubleValue << stringValue;
// 输出:42 3.14 Hello
QVariant variantDate = QDate(2024, 11, 27); // 存储 QDate
QVariant variantColor = QColor(255, 0, 0); // 存储 QColor
QDate date = variantDate.toDate();
QColor color = variantColor.value<QColor>();
qDebug() << date.toString() << color.name();
// 输出:2024-11-27 #ff0000
QVariant
在 Qt 的模型-视图框架中起着重要作用,数据通常通过 QVariant
来封装并传递。
QVariant variantData = model->data(index);
if (variantData.canConvert<int>()) {
int value = variantData.toInt();
qDebug() << "Data is of type int:" << value;
}
QVariant
支持多种类型转换,可以通过 toType()
方法进行数据类型的转换。
QVariant variantInt = 100;
QString stringValue = variantInt.toString(); // 将 int 转换为 QString
qDebug() << stringValue; // 输出:100
QVariant
提供了方便的比较运算符来比较两个对象是否相等。
QVariant variant1 = 100;
QVariant variant2 = 100;
QVariant variant3 = 200;
if (variant1 == variant2) {
qDebug() << "variant1 is equal to variant2"; // 输出:variant1 is equal to variant2
}
if (variant1 != variant3) {
qDebug() << "variant1 is not equal to variant3"; // 输出:variant1 is not equal to variant3
}
QVariant
可以与 STL 类型进行转换,如 std::string
、std::vector
等。
std::string stdString = "Hello from STL";
QVariant variant = QVariant::fromValue(stdString);
std::string convertedString = variant.value<std::string>();
qDebug() << QString::fromStdString(convertedString);
// 输出:Hello from STL
如果你需要存储自定义类型,可以通过 Q_DECLARE_METATYPE
和 qVariantFromValue()
来实现。
struct MyStruct {
int a;
double b;
};
Q_DECLARE_METATYPE(MyStruct)
MyStruct myStruct = { 1, 3.14 };
QVariant variant = QVariant::fromValue(myStruct);
MyStruct retrievedStruct = variant.value<MyStruct>();
qDebug() << "a:" << retrievedStruct.a << "b:" << retrievedStruct.b;
QVariant
是一个非常强大的数据封装类,它能够存储多种类型的数据,并支持类型转换。无论是基本数据类型、Qt 数据类型,还是自定义类型,都可以通过 QVariant
进行管理。它是 Qt 框架中实现模型-视图、信号槽、数据库操作等机制的重要组成部分。通过合理使用 QVariant
,可以大大简化跨类型的数据操作和转换,提高程序的灵活性与可扩展性。