Qt文档阅读笔记-关于Q_DECLARE_METATYPE原理以及使用

 

目录

官方解释

博主补充小栗子

最简单的关于Q_DECLARE_METATYPE的例子:

关于qRegisterMetaType的栗子


 

官方解释

Q_DECLARE_METATYPE(Type)

这个宏是为了让QMetaType知道Type这个数据类型,并提供一个默认的拷贝构造函数和析构函数。QVariant需要使用Q_DECLARE_METATYPE这个宏来定制类型。

当使用这个宏的时候要求Type是一个完整的数据类型。可以使用Q_DECLARE_OPAQUE_POINTER()来注册一个指针用于转发声明类型。

一般都把这个宏放到结构体或类的末尾【注意:这是官方说的】,如果不放到末尾也是阔以的,就放到头文件中,当你用 QVariant就要包含那个.h,个人觉得这非常不适合面向对象以及模块化编程。

通过添加Q_DECLARE_METATYPE()这个宏让QOject及其子类知道这个类型。这里要注意的是如果要在队列信号(关于connect函数队列信号请看这篇博文:https://blog.csdn.net/qq78442761/article/details/81937837)中使用或者用用槽连接,要先调用这个函数qRegisterMetaType()【这里是在运行的时候,对他进行注册】

下面是官方给出的一个小栗子:

  struct MyStruct
  {
      int i;
      ...
  };

  Q_DECLARE_METATYPE(MyStruct)

栗子二:

  namespace MyNamespace
  {
      ...
  }

  Q_DECLARE_METATYPE(MyNamespace::MyStruct)

以及如何在QVariant中使用的栗子:

  MyStruct s;
  QVariant var;
  var.setValue(s); // copy s into the variant

  ...

  // retrieve the value
  MyStruct s2 = var.value<MyStruct>();

下面这几个类型是自动注册的,不需要使用Q_DECLARE_METATYPE这个宏:
1.QObject继承下来的子类的指针;
2.QList<T>, QVector<T>, QQueue<T>, QStack<T>, QSet<T> or QLinkedList<T>这些T都是自动注册的;
3.QHash<T1, T2>, QMap<T1, T2> or QPair<T1, T2> T1,和T2都是自动注册的;
4.QPointer<T>, QSharedPointer<T>, QWeakPointer<T>这3个T必须是QObject的子类;
5.枚举类型要用Q_ENUM or Q_FLAG;
6.拥有Q_GADGET宏的类。

下面是我自己的例子,用于对Q_DECLARE_METATYPE这一知识点的补充!

 

博主补充小栗子

最简单的关于Q_DECLARE_METATYPE的例子:

源码如下:

mydatatype.h

#ifndef MYDATATYPE_H
#define MYDATATYPE_H

#include <QMetaType>


class MyDataType
{
public:
    MyDataType();
    int value_a;
    int value_b;
    int value_c;
};

Q_DECLARE_METATYPE(MyDataType)

#endif // MYDATATYPE_H

main.cpp

#include <QApplication>
#include "mydatatype.h"
#include <QVariant>
#include <QDebug>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MyDataType *myDataType=new MyDataType;
    QVariant var;
    var.setValue(*myDataType);
    qDebug()<<var;


    MyDataType my=var.value<MyDataType>();
    qDebug()<<my.value_a<<" "<<my.value_b<<" "<<my.value_c;

    delete myDataType;

    return a.exec();
}

mydatatype.cpp

#include "mydatatype.h"

MyDataType::MyDataType()
{
    value_a=0;
    value_b=1;
    value_c=2;
}

运行截图如下:

 

关于qRegisterMetaType的栗子

关于qRegisterMetaType的解释,在明天将会给出官方的详细说明,在此先会用就阔以了!

源码如下:

mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class MyWidget;
}

struct MyData{
    QString str;
};

Q_DECLARE_METATYPE(MyData)

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();

signals:
    void sendData(MyData myWidget);

public slots:
    void textChanged(QString str);

private:
    Ui::MyWidget *ui;
    QString m_str;
};


#endif // MYWIDGET_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "mywidget.h"

class MyWidget;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void btnClicked();
    void receiverData(MyData var);

private:
    Ui::Widget *ui;

    MyWidget *m_mywidget;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

mywidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    connect(ui->lineEdit,SIGNAL(textChanged(QString)),this,SLOT(textChanged(QString)));

    qRegisterMetaType<MyData>();
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::textChanged(QString str)
{
    MyData myData;
    myData.str=str;
    sendData(myData);
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_mywidget=new MyWidget;
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(btnClicked()));
    connect(m_mywidget,SIGNAL(sendData(MyData)),this,SLOT(receiverData(MyData)),Qt::QueuedConnection);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::btnClicked()
{
    m_mywidget->show();
}

void Widget::receiverData(MyData var)
{
    ui->lineEdit->setText(var.str);
}

运行截图如下:

继承于QObject的类,我就不演示了,因为C/C++中有个赋值兼容的知识点,估计就是通过这个赋值兼容,使得继承于QObject的类,QMetaType直接能够识别!自己进加到他的元对象系统!!!

展开阅读全文
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值