目录
1. 前言
2. qRegisterMetaTypeStreamOperators
2.1. 函数功能简述
2.2.用法举例1
3. qRegisterMetaType
1. 前言
Qt通过qRegister开头的函数和Q_DECLARE开头的几个宏向Qt元系统注册、声明一些非基本类型。一旦声明、注册后,在Qt元系统中就可以很方便的利用这些非基本类型,这样对编程中的数据交互很方便。非基本类型是指除了一些基本类型之外的类型,如:除了int、float、qint......之外的类型,如:自定义类、结构体、枚举等。
有关Q_DECLARE开头的几个宏的用法说明,请参见如下博文:
《Qt中以Q_DECLARE开头的几个宏的用法说明》。
2. qRegisterMetaTypeStreamOperators
2.1. 函数功能简述
该函数如下:
template <typename T>
void qRegisterMetaTypeStreamOperators(const char *typeName)
在Qt Assisant中省略了前面的模板声明关键字。这个函数为类型为T,名称为typeName(即参数)向Qt元系统注册流操作,之后,类型T就能用 如下函数执行流相关的操作:
static] bool QMetaType::load(QDataStream &stream, int type, void *data)
bool QMetaType::save(QDataStream &stream, int type, const void *data)
当流化一个QVariant对象时,常常会用到这个函数。如下:
qRegisterMetaTypeStreamOperators<MyClass>("MyClass");
流操作应实现如下的函数,否则编译会报错:
QDataStream &operator<<(QDataStream &out, const MyClass &myObj);
QDataStream &operator>>(QDataStream &in, MyClass &myObj);
2.2.用法举例1
#include <QtCore/QCoreApplication>
#include<QVariant>
#include<QDataStream>
#include <QBuffer>
class CMyObj : public QObject
{
public:
CMyObj()
{
m = 888;
}
~CMyObj()
{
}
CMyObj(const CMyObj& obj)
{
m = obj.m;
}
int getM() const
{
return m;
}
void setM(int nMy_m)
{
m = nMy_m;
}
private:
int m;
};
Q_DECLARE_METATYPE(CMyObj);
QDataStream& operator<< (QDataStream& stream, const CMyObj& myObj)
{
auto m = myObj.getM();
stream << m;
return stream;
}
QDataStream& operator>> (QDataStream& stream, CMyObj& myObj)
{
int m;
stream >> m;
myObj.setM(m);
return stream;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 对CMyObj类注册流化操作
qRegisterMetaTypeStreamOperators<CMyObj>("CMyObj");
/* CMyObj saveMyObj;
QVariant varSave;
varSave.setValue(saveMyObj);
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream streamForSaveMyObj(&file);
streamForSaveMyObj << varSave;
file.close();
file.open(QIODevice::ReadOnly);
QVariant varLoad;
streamForSaveMyObj >> varLoad;
auto k = varLoad.value<CMyObj>();
auto m = k.getM();
file.close();*/
CMyObj saveMyObj;
QVariant varSave;
// 将CMyObj类的saveMyObj对象保存到QVariant,注意:需要用Q_DECLARE_METATYPE声明,否则编译会报错
varSave.setValue(saveMyObj);
QBuffer buf;
QDataStream streamForSaveMyObj(&buf);
buf.open(QIODevice::WriteOnly);
streamForSaveMyObj << varSave; // 将QVariant保存到流,QBuffer你可以认为是一段内存。将其保存到一段内存中。
buf.close();
buf.open(QIODevice::ReadOnly);
QVariant varLoad;
streamForSaveMyObj >> varLoad; // 将原先保存到内存的流中的QVariant对象取出来
buf.close();
auto loadMyObj = varLoad.value<CMyObj>(); // 从QVariant对象中恢复出原先的CMyObj类对象
auto m = loadMyObj.getM(); // 输出888
return a.exec();
}
说明:
- 当将一个自定义的类,进行流化操作时,必须用qRegisterMetaTypeStreamOperators进行声明,否则编译会报错。如下:
- 当将自定义的类对象保存到QVariant对象时,需要先用 用Q_DECLARE_METATYPE声明,否则编译会报错。具体参见:Qt中以Q_DECLARE开头的几个宏的用法说明。
- 上面的代码将一个自定义的对象通过流保存到QBuffer对象中。QBuffer对象可以认为是内存中的一块区域。也可以像注释掉的那块代码那样保存到文件。
- 上面代码将自定义对象写入流和从流读取出来放到main的同一个函数。实际开发中,可以利用类的成员变量进行跨函数数据交互,如:在类的A成员函数中将自定义对象写入流(该流是类的成员变量);然后在类的B成员函数中再将该自定义对象从流中读出来,这样可以方便数据的交互。
3. qRegisterMetaType
这个参见Qt assist,在此不再详述。