Qt 提供的类型如 QString, QSize 和 QColor 等可以存储在 QVariant 里,并且作为 QObject 及其子类的属性使用,例如调用 obj.setProperty("name", QString("道格拉斯·狗"))
, obj.property("name")
,也可以在信号槽中作为参数传递。我们自定义的类如果也想要这么使用,需要使用 Q_DECLARE_METATYPE 和 qRegisterMetaType 来注册后才行。
自定义类型和 QVariant 转换
如果要 QVariant 支持自定义类型,需要使用 Q_DECLARE_METATYPE 注册一下自定义类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <QDebug> #include <QObject>
class Foo { public: int amount; };
Q_DECLARE_METATYPE(Foo)
int main(int argc, char *argv[]) { Q_UNUSED(argc) Q_UNUSED(argv)
Foo foo; foo.amount = 123;
QVariant var = QVariant::fromValue(foo); qDebug() << var.value<Foo>().amount;
return 0; }
|
使用 Q_DECLARE_METATYPE(Foo) 后就能使用 QVariant 存储自定义类型 Foo 了
自定义类型作为 QObject 的属性
自定义类型想作为 QObject 的属性使用,除了调用 Q_DECLARE_METATYPE(Foo) 之外,还需要实现运算符 QVariant
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include <QDebug> #include <QObject>
class Foo { public: operator QVariant() const { return QVariant::fromValue(*this); }
int amount; };
Q_DECLARE_METATYPE(Foo)
int main(int argc, char *argv[]) { Q_UNUSED(argc) Q_UNUSED(argv)
Foo foo; foo.amount = 123;
QObject obj; obj.setProperty("foo", foo); qDebug() << obj.property("foo").value<Foo>().amount;
return 0; }
|
信号槽中使用自定义类型
调用 Q_DECLARE_METATYPE(Foo) 之后,Foo 可以在连接类型为 Qt::DirectConnection 的信号槽中使用了,也就是同一个线程中,如果要在多线程的信号槽中使用自定义类型,还需要调用 qRegisterMetaType<Foo>()
,一般都是在 main() 函数中调用或者在某个构造函数中调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <QDebug> #include <QObject>
class Foo { public: int amount; };
Q_DECLARE_METATYPE(Foo)
int main(int argc, char *argv[]) { Q_UNUSED(argc) Q_UNUSED(argv)
qRegisterMetaType<Foo>(); connect(...)
return 0; }
|