Qt5.3文档翻译:QVariant类,QVariant Class
QVariant 类,可当作一个联合体来使用,用来容纳常用的Qt 数据类型。 详情……
头文件: |
#include <QVariant> |
qmake: |
QT += core |
QVariant类,可当作一个联合体来使用,用来容纳常用的Qt 数据类型。
因为C++禁止 在联合体中包含那些没有默认构造函数和析构函数的类型,所以, 大部分有趣的 Qt 类都无法被用于联合体中。如果 不使用 QVariant 的话,那么, QObject::property () 、数据库以及别的相关的某些功能就会出现问题。
每个QVariant对象 ,在同一时刻,会储存单一 的某个类型( type ())的一个单一的值。 (某些类型 ( type ())本身是有多个值的,例如字符串列表。 ) 妳可以:得知 该变量储存着的是哪个类型, T ;使用 convert () 来将它转换为另一种类型;使用某个toT()函数 (例如 toSize ())来获取它的值; 以及,使用 canConvert ()来检查该类型是否可以被转换为某个特定的类型。
那些toT()方法(例如 toInt () 、 toString ()) 都是常量类型(const)的。如果 妳要求获取其中所存储的类型的值,则,它们会返回所存储的对象的一个副本。如果 妳要求获取到可由所存储的类型转换而得到的某个类型的值,则, toT() 会进行复制、转换,而原样保留其中所存储的对象本身。如果 妳要求获取到不可由所存储的类型转换而得到的某个类型的值,则,结果取决于该类型本身;参考对应的函数文档以了解细节。
以下是一些QVariant 示例代码:
QDataStream out(...);
QVariant v(123); // 现在,这个变量中包含着一个整数int
int x = v. toInt (); // x = 123
out << v; // 向输出流out中写入一个类型标记和一个整数int
v = QVariant("hello"); // 现在,这个变量中包含着一个QByteArray
v = QVariant(tr("hello")); // 现在,这个变量中包含着一个QString
int y = v. toInt (); // y = 0 ,因为 v无法 被转换为整数 int
QString s = v. toString (); // s = tr("hello") (参考QObject::tr())
out << v; // 向输出流out中写入一个类型标记和一个QString
...
QDataStream in(...); // (打开之前输出 的流 )
in >> v; // 读取一个整数Int变量
int z = v. toInt (); // z = 123
qDebug ("Type is %s", // 输出"Type is int"
v.typeName());
v = v. toInt () + 100; // 现在,这个变量中存储的值是 223
v = QVariant ( QStringList ());
妳甚至还可以在变量(variant)里存储 QList <QVariant>和 QMap < QString , QVariant>类型的值,所以 ,妳可以轻易地创建任意复杂的数据结构,来容纳任意类型。 这就使得它功能强大、多才多艺,但是, 与那种以标准数据结构来存储特定类型的方式相比,这种方式在内存及速度上的性能可能会差一些。
QVariant也支持空(null)值的概念,也就是,妳可以存储一个类型确定却没有设置值的对象。但是,要注意,那些QVariant类型,只有在设置过值的情况下,才能够被转换类型。
QVariant x, y( QString ()), z( QString (""));
x. convert ( QVariant ::Int);
// x.isNull() == true
// y.isNull() == true, z.isNull() == false
QVariant 可被扩展, 以支持那些未在 Type ( 已废弃 ) 枚举中列出的类型。参考 QMetaType 文档 以了解细节。
因为QVariant 是Qt Core 模块的一部分,所以, 它无法提供对于那些在Qt GUI 中定义的数据类型的转换函数,例如 QColor 、 QImage 和 QPixmap 。 换句话说,不存在 toColor() 函数 。作为替代手段 ,妳可以使用 QVariant::value () 或 qvariant_cast ()模板函数 。例如:
QVariant variant;
...
QColor color = variant.value< QColor >();
反向转换(例如, 从 QColor 转换 为 QVariant) ,对于QVariant 支持的所有数据类型,都是自动进行的,包括那些与图形界面相关的类型:
QColor color = palette().background().color();
QVariant variant = color;
当妳连招使用 canConvert () 和 convert () 的时候, 可能会发生: canConvert () 返回真(true), 而 convert ()返回 假(false)。 这种情况,一般是因为, canConvert ()返回 的值的意义是, 在给定了适当的数据的前提下,QVariant 能否在两种类型之间转换; 妳仍然可能向它提供那种实际上无法转换的数据。
例如,对于一个包含着字符串的变量,妳调用canConvert(Int)时,会返回真(true),因为,一般情况下,QVariant能够将那些由数字组成的字符串转换成整数。然而,如果字符串中包含着非数字的字符,则,它无法被转换成整数,这种情况下,尝试将它转换成整数就会失败。因此,只有当这两个函数都返回真(true)的情况下,才是转换成功了。
参考 QMetaType 。
构造一个类型为 type 的空(null)变量(variant)。
如果 本变量的类型可被转换为所请求的目标类型 targetTypeId ,则返回真( true )。 当妳调用 toInt ()、 toBool ()等方法时,这种转换是自动进行的。
下列转换会自动进行:
对于 一个包含着指向某个继承了 QObject 的类型的指针的 QVariant ,如果qobject_cast 对于 这里所提供的目标类型 targetTypeId 能够成功的话,则此函数也会返回真 (true) 。注意 ,仅仅对于那些 QObject 子类才有效,它们使用了 Q_OBJECT 宏。
对于 一个包含了一个序列性容器的 QVariant ,如果目标类型 targetTypeId 是 QVariantList ,则此函数也会返回真(true)。 可以在不将它提取为一个 QVariantList (副本)的前提下, 对其内容进行迭代访问:
QList < int > intList;
intList.push_back(7);
intList.push_back(11);
intList.push_back(42);
QVariant variant = QVariant :: fromValue (intList);
if (variant.canConvert< QVariantList >()) {
QSequentialIterable iterable = variant.value< QSequentialIterable >();
// 可以使用 foreach:
foreach (const QVariant &v, iterable) {
qDebug () << v;
}
// 可以使用 C++11 的带范围的 for:
for (const QVariant &v : iterable) {
qDebug () << v;
}
// 可使用迭代器:
QSequentialIterable ::const_iterator it = iterable.begin();
const QSequentialIterable ::const_iterator end = iterable.end();
for ( ; it != end; ++it) {
qDebug () << *it;
}
}
这要求该容器的值类型本身是一个元类型。
类似 于,对于一个包含了一个序列性容器的 QVariant ,如果目标类型 targetTypeId 是 QVariantHash 或 QVariantMap ,则此函数也会返回真(true)。 可以在不将它提取为一个 QVariantHash 或 QVariantMap (副本)的情况下,对其内容进行迭代访问:
QHash < int , QString > mapping;
mapping.insert(7, "Seven");
mapping.insert(11, "Eleven");
mapping.insert(42, "Forty-two");
QVariant variant = QVariant :: fromValue (mapping);
if (variant.canConvert< QVariantHash >()) {
QAssociativeIterable iterable = variant.value< QAssociativeIterable >();
// 可对其中的值使用 foreach :
foreach (const QVariant &v, iterable) {
qDebug () << v;
}
// 可对其中的值使用 C++11 的带范围的 for :
for (const QVariant &v : iterable) {
qDebug () << v;
}
// 可使用迭代器:
QAssociativeIterable ::const_iterator it = iterable.begin();
const QAssociativeIterable ::const_iterator end = iterable.end();
for ( ; it != end; ++it) {
qDebug () << *it; // 当前 值
qDebug () << it.key();
qDebug () << it.value();
}
}
参考 convert () 、 QSequentialIterable 、 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE () 、 QAssociativeIterable 和 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE () 。
如果 本变量可被转换为目标模板类型 T ,则返回真( true ),否则返回假(false)。
示例:
QVariant v = 42;
v.canConvert<int>(); // 返回真
v.canConvert< QString >(); // 返回 真
MyCustomStruct s;
v. setValue (s);
v.canConvert<int>(); // 返回假
v.canConvert<MyCustomStruct>(); // 返回真
对于 一个包含着指向某个继承了 QObject 的类型的指针的 QVariant ,如果qobject_cast 对于 这里所提供的目标模板类型 T 能够成功的话,则此函数也会返回真 (true) 。
参考 convert () 。
将本变量转换为所要求的类型 targetTypeId 。如果转换无法完成 ,则此变量会被清空。如果转换成功, 则返回真( true );否则返回假( false )。
对于 一个包含着指向某个继承了 QObject 的类型的指针的 QVariant ,如果qobject_cast 对于 这里所提供的目标模板类型 T 能够成功的话,则此函数也会转换成功并且返回真 (true) 。注意 ,仅仅对于那些 QObject 子类才有效,它们使用了 Q_OBJECT 宏。
警告: 由于历史原因 ,对 一个空(null)的 QVariant 进行转换 的话, 会产生目标类型的一个空(null)值(例如,对于 QString 会返回一个空白字符串 ),并且返回假(false)。
See also canConvert () and clear ().
返回 一个包含着值 value 的一个副本的 QVariant 。其它方面 ,与 setValue ()的行为一致。
示例:
MyCustomStruct s;
return QVariant ::fromValue(s);
注意 : 如果 妳在使用自定义类型的话,则,妳应当使用 Q_DECLARE_METATYPE ()宏 来注册妳的自定义类型。
储存 值 value 的一个副本。如果 QVariant 不支持 T 所代表的类型, 则, 会使用 QMetaType 来储存该值。如果 QMetaType 不支持该类型的话,会发生一个编译错误。
示例:
QVariant v;
v.setValue(5);
int i = v. toInt (); // 现在 , i 是 5
QString s = v. toString () // 现在 , s 是 "5"
MyCustomStruct c;
v.setValue(c);
...
MyCustomStruct c2 = v.value<MyCustomStruct>();
参考 value () 、 fromValue () 和 canConvert () 。
返回 此变量中存储的值的存储类型。尽管 这个函数被声明为返回 QVariant::Type ( 已废弃 ) ,但是, 妳应当将其返回值解释为 QMetaType::Type 。特别 是,如果返回 值大于等于 QMetaType::User 的话,则会返回 QVariant::UserType ( 已废弃 ) 。
注意 , 从 QVariant::Char ( 已废弃 ) 到 QVariant::RegExp ( 已废弃 ) 范围以及从 QVariant::Font ( 已废弃 ) 到 QVariant::Transform ( 已废弃 ) 范围的返回值,对应着从 QMetaType::QChar 到 QMetaType::QRegExp 范围内的值以及从 QMetaType::QFont 到 QMetaType::QQuaternion 范围内的值。
当妳在使用字符 (char) 以及 QChar 变量时,要特别注意。注意 ,没有专门针对字符 (char) 类型 的 QVariant 构造函数,但是 有针对 QChar 的构造函数。对于 一个类型为 QChar 的变量, 此函数会返回 QVariant::Char ( 已废弃 ) , 它等价于 QMetaType::QChar ,但是,对于一个类型为字符( char )的变量, 此函数会返回 QMetaType::Char , 它 并不 等价于 QVariant::Char ( 已废弃 ) 。
另外 ,注意, 这些类型 void* 、 long 、 short 、 unsigned long 、 unsigned short 、 unsigned char 、 float 、 QObject* 和 QWidget* 都在 QMetaType::Type 中有对应的值,但是在 QVariant::Type ( 已废弃 ) 中没有对应的值,它们可被此函数返回。但是,如果 妳拿 QVariant::Type ( 已废弃 ) 来对它们进行测试的话,它们 会被认为是用户定义的类型。
要想测试一个包含着某个数据类型的 QVariant 实例是否与妳所感兴趣的数据类型相兼容的话, 则使用 canConvert ()。
返回 此变量中储存的类型的名字。 所返回的字符串,会说明用来存储此数据的C++数据类型:例如 , " QFont " 、 " QString " 或 " QVariantList " 。无效 的变量会返回 0 。
将储存类型的整数表示值 typeId ,转换为它的字符表示值。
如果 其类型为 QMetaType::UnknownType 或者不存在,则会返回一个空(null)指针。
返回 所存储的值被转换为模板类型 T 的结果。调用 canConvert () 来确定是否可以转换为某个类型。如果实际 的值无法被转换的话,则会返回一个 默认构造 的值 。
如果 QVariant 支持类型 T 的话,则,此函数与 toString () 、 toInt ()等等函数的行为一致。
示例:
QVariant v;
MyCustomStruct c;
if (v.canConvert<MyCustomStruct>())
c = v.value<MyCustomStruct>();
v = 7;
int i = v.value<int>(); // 等价于v.toInt()
QString s = v.value< QString >(); // 等价 于 v.toString() ,现在, s 是 "7"
MyCustomStruct c2 = v.value<MyCustomStruct>(); // 转换失败,c2为空
如果 该 QVariant 中包含着一个指向某个继承了 QObject 的类型的对象的指针,那么, T 可以是任意的 QObject 类型。如果 该 QVariant 中储存的指针可通过qobject_cast 转换为T,则, 会返回该结果。否则, 会返回一个空(null)指针。注意 ,这只对使用了 Q_OBJECT 宏的那些 QObject 子类有效。
如果 该 QVariant 中包含着一个序列性的容器,并且 T 是 QVariantList ,则, 该容器中的那些元素会被转换为 QVariants ,并且此函数会返回一个 QVariantList 。
QList < int > intList;
intList.push_back(7);
intList.push_back(11);
intList.push_back(42);
QVariant variant = QVariant :: fromValue (intList);
if (variant.canConvert< QVariantList >()) {
QSequentialIterable iterable = variant.value< QSequentialIterable >();
// 可使用 foreach:
foreach (const QVariant &v, iterable) {
qDebug () << v;
}
// 可使用 C++11 的带范围的 for:
for (const QVariant &v : iterable) {
qDebug () << v;
}
// 可使用迭代器:
QSequentialIterable ::const_iterator it = iterable.begin();
const QSequentialIterable ::const_iterator end = iterable.end();
for ( ; it != end; ++it) {
qDebug () << *it;
}
}
参考 setValue () 、 fromValue () 、 canConvert () 和 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE () 。
Your opinionsHxLauncher: Launch Android applications by voice commands