Qt中以qRegister开头的几个函数的用法说明

目录

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 
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");

流操作应实现如下的函数,否则编译会报错:

  QDataStream &operator<<(QDataStream &out, const MyClass &myObj);
  QDataStream &operator>>(QDataStream &in, MyClass &myObj);

    2.2.用法举例1

#include 
#include
#include
#include  
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 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();
    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(); // 从QVariant对象中恢复出原先的CMyObj类对象
    auto m = loadMyObj.getM(); // 输出888

    return a.exec();
}

说明:

  • 当将一个自定义的类,进行流化操作时,必须用qRegisterMetaTypeStreamOperators进行声明,否则编译会报错。如下:Qt中以qRegister开头的几个函数的用法说明_第1张图片
  • 当将自定义的类对象保存到QVariant对象时,需要先用 用Q_DECLARE_METATYPE声明,否则编译会报错。具体参见:Qt中以Q_DECLARE开头的几个宏的用法说明。
  • 上面的代码将一个自定义的对象通过流保存到QBuffer对象中。QBuffer对象可以认为是内存中的一块区域。也可以像注释掉的那块代码那样保存到文件。
  • 上面代码将自定义对象写入流和从流读取出来放到main的同一个函数。实际开发中,可以利用类的成员变量进行跨函数数据交互,如:在类的A成员函数中将自定义对象写入流(该流是类的成员变量);然后在类的B成员函数中再将该自定义对象从流中读出来,这样可以方便数据的交互。

3. qRegisterMetaType

这个参见Qt assist,在此不再详述。

你可能感兴趣的:(QT,qt,开发语言)