qt-C++笔记之Q_DECLARE_METATYPE和qRegisterMetaType
code review!
文章目录
- qt-C++笔记之Q_DECLARE_METATYPE和qRegisterMetaType
- 一.Q_DECLARE_METATYPE
- 使用方法
- 应用场景
- 二.为什么需要注册类型?
- 三.使用 Q_DECLARE_METATYPE 处理自定义类型的简短示例
- 3.1.自定义类型定义
- 3.2.在 QVariant 中存储和检索
- 3.3.在信号和槽中传递
一.Q_DECLARE_METATYPE
Q_DECLARE_METATYPE
是一个 Qt 宏,用于注册某种类型以便在 Qt 的元对象系统中使用。注册后的类型可以在 Qt 的信号和槽机制中使用,特别是当类型作为信号参数传递时。这对于非Qt内建类型来说尤其重要,因为 Qt 的元对象系统需要额外的信息来处理这些类型。
使用方法
-
声明自定义类型:
首先需要创建一个自定义类型。例如:
class MyCustomType { public: int someValue; };
-
使用
Q_DECLARE_METATYPE
:在全局命名空间中使用这个宏来声明自定义类型:
Q_DECLARE_METATYPE(MyCustomType)
-
注册类型:
为了使 QVariant 能够处理这个自定义类型,还需要在程序的某个地方注册它:
qRegisterMetaType<MyCustomType>("MyCustomType");
应用场景
- 信号和槽: 如果想在信号和槽中传递这个类型的对象,需要注册。
- QVariant: 如果想将自定义类型存储在 QVariant 中。
这样,就可以在 Qt 的各种机制中使用自定义类型了。
二.为什么需要注册类型?
Qt 的信号和槽机制以及变量属性系统依赖于运行时类型信息来动态地进行类型检查和转换。注册类型允许 Qt 知道如何在不同组件间安全地传递这些类型的数据,特别是在不同线程之间。比如,如果想在信号中传递一个自定义数据结构或者 STL 容器,就必须先使用 Q_DECLARE_METATYPE
进行注册。
三.使用 Q_DECLARE_METATYPE 处理自定义类型的简短示例
3.1.自定义类型定义
首先定义一个简单的自定义类型:
// customtype.h
#ifndef CUSTOMTYPE_H
#define CUSTOMTYPE_H
#include <QString>
class CustomType {
public:
CustomType() : name("Default") {}
CustomType(const QString &name) : name(name) {}
QString getName() const { return name; }
void setName(const QString &name) { this->name = name; }
private:
QString name;
};
Q_DECLARE_METATYPE(CustomType)
#endif // CUSTOMTYPE_H
3.2.在 QVariant 中存储和检索
接下来,演示如何将自定义类型存储到 QVariant
中,并从中检索。
// main.cpp
#include <QCoreApplication>
#include <QVariant>
#include <QDebug>
#include "customtype.h"
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
// 注册类型
qRegisterMetaType<CustomType>("CustomType");
// 创建一个自定义类型实例
CustomType original("Example");
// 存储在 QVariant 中
QVariant variant = QVariant::fromValue(original);
// 从 QVariant 中检索
if (variant.canConvert<CustomType>()) {
CustomType retrieved = variant.value<CustomType>();
qDebug() << "Retrieved name:" << retrieved.getName();
}
return 0;
}
3.3.在信号和槽中传递
最后,展示如何在信号和槽中传递自定义类型。
// sender.h
#ifndef SENDER_H
#define SENDER_H
#include <QObject>
#include "customtype.h"
class Sender : public QObject {
Q_OBJECT
public:
void send() {
CustomType data("Signal Data");
emit customSignal(data);
}
signals:
void customSignal(CustomType data);
};
#endif // SENDER_H
// receiver.h
#ifndef RECEIVER_H
#define RECEIVER_H
#include <QObject>
#include <QDebug>
#include "customtype.h"
class Receiver : public QObject {
Q_OBJECT
public slots:
void onCustomSignal(CustomType data) {
qDebug() << "Received name:" << data.getName();
}
};
#endif // RECEIVER_H
// main.cpp
#include <QCoreApplication>
#include "sender.h"
#include "receiver.h"
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
qRegisterMetaType<CustomType>("CustomType");
Sender sender;
Receiver receiver;
QObject::connect(&sender, &Sender::customSignal, &receiver, &Receiver::onCustomSignal);
sender.send();
return app.exec();
}