Qt文档阅读笔记-qRegisterMetaType()的原理及其使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq78442761/article/details/82107880

目录

 

官方介绍

博主栗子


官方介绍

调用这个函数去注册类型T,这个T要使用Q_DECLARE_METATYPE()进行声明,返回meta type id,如下:

int id = qRegisterMetaType<MyStruct>();

这个函数需要他在被调用时有完整的定义。如果是指针类型他需要有完整的定义。使用Q_DECLARE_OPAQUE_POINTER()去注册指针用于转发数据类型。
使用Q_DECLARE_METATYPE()可以让这个数据类型T放到QVariant里面。如果想以队列的方式让T使用信号与槽,当第一次连接的时候就要调用qRegisterMetaType<T>()。
QObject::property()要和类型T一起使用,这个时候qRegisterMetaType<T>()要提前调用。通常把这个函数放到类型T的构造函数里面,或者main函数里面进行调用。
注意:这个函数是线程安全的

博主栗子

程序运行截图如下:

源码如下:

myworker.h

#ifndef MYWORKER_H
#define MYWORKER_H

#include <QThread>

struct MyData{
    QString str;
};

Q_DECLARE_METATYPE(MyData)

class MyWorker : public QThread
{
    Q_OBJECT
public:
    explicit MyWorker(QObject *parent = 0);
    void create(int time);
    void destroy();

signals:
    void sendMeg(MyData mydata);

private:
    void run();
    int m_time;
    bool exitStatus;
};

#endif // MYWORKER_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

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

class MyData;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

protected:
    void closeEvent(QCloseEvent *event)Q_DECL_OVERRIDE;

signals:
    sendData(MyData *data);

public slots:
    void receiveData(MyData mydata);
    void exitThread();

private:
    Ui::Widget *ui;
    MyWorker m_myWorker[5];
};

#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();
}

myworker.cpp

#include "myworker.h"
#include <QVariant>
#include <QDebug>

MyWorker::MyWorker(QObject *parent) : QThread(parent)
{
    qRegisterMetaType<MyData>();
    exitStatus=false;
}

void MyWorker::create(int time)
{
    m_time=time;
    start();
}

void MyWorker::destroy()
{
    exitStatus=true;
}

void MyWorker::run()
{
    while(true&&!exitStatus){
        MyData myData;
        myData.str="currentThreadID:"+QString::number((unsigned int)QThread::currentThreadId())+" address 0x:"+QString::number((unsigned int)this,16);
        QThread::msleep(m_time);
        emit sendMeg(myData);
    }
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QEventLoop>
#include <QTimer>
#include <QCloseEvent>


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    for(int i=0;i<5;i++){
        m_myWorker[i].create(1000+1*1000);
        connect(&m_myWorker[i],SIGNAL(sendMeg(MyData)),this,SLOT(receiveData(MyData)),Qt::QueuedConnection);    //多线程中默认也是Qt::QueuedConnection
    }
}

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

void Widget::closeEvent(QCloseEvent *event)
{
    QEventLoop loop;
    QTimer::singleShot(100,this,SLOT(exitThread()));
    QTimer::singleShot(1000*2,this,SLOT(close()));
    QTimer::singleShot(1.5*1000,&loop,SLOT(quit()));
    loop.exec();
    event->accept();
}

void Widget::receiveData(MyData mydata)
{
    ui->listWidget->insertItem(0,mydata.str);
}

void Widget::exitThread()
{
    for(int i=0;i<5;i++){
        m_myWorker[i].destroy();
    }
}

猜你喜欢

转载自blog.csdn.net/qq78442761/article/details/82107880