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 valueMyStruct 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_Hmain.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_OBJECTpublic: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_Hwidget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include "mywidget.h"class MyWidget;namespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();public slots:void btnClicked();void receiverData(MyData var);private:Ui::Widget *ui;MyWidget *m_mywidget; };#endif // WIDGET_Hmain.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直接能夠識別!自己進加到他的元對象系統!!!
總結
以上是生活随笔為你收集整理的Qt文档阅读笔记-关于Q_DECLARE_METATYPE原理以及使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++工作笔记-对继承的进一步认识
- 下一篇: Qt文档阅读笔记-TextEdit QM