> 文档中心 > QT怎么发送带结构体数据的信号

QT怎么发送带结构体数据的信号

当发送的信号结构体时

第一步:定义一个结构体.并在包含该结构体的类里面注册该结构体,通过此方法Q_DECLARE_METATYPE(T).

第二步:作为信号输出时,不能直接传结构体,要先包装一下结构再传出去; 接收时,也要拆开包装,才能拿到数据,这里借助QVariant ;

最后一步:连接信号.

具体实例如下:

.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include #includestruct SRT_STUDENT{    int age;    char name[20];};Q_DECLARE_METATYPE(SRT_STUDENT)//注册结构体class MainWindow : public QMainWindow{    Q_OBJECT    public:    MainWindow(QWidget *parent = 0);    ~MainWindow();    void sendSig();public slots:    void receiveSig(QVariant varValue);signals:    void sig_StudentInfo(QVariant varValue);//自定义的信号};#endif // MAINWINDOW_H

.cpp

#include "mainwindow.h"#include MainWindow::MainWindow(QWidget *parent)    : QMainWindow(parent){connect(this,SIGNAL(sig_StudentInfo(QVariant)),this,SLOT(receiveSig(QVariant)));}MainWindow::~MainWindow(){    }void MainWindow::sendSig(){    SRT_STUDENT stu;    QVariant varValue; //QT中可以装任何数据的类    memset(&stu, 0, sizeof(stu));    stu.age = 20;    strcpy(stu.name,"lili");    varValue.setValue(stu);//把结构体添加QVariant    for(int i=0;i<5;i++)    { if(i==4) {     emit sig_StudentInfo(varValue);     break; }    }}void MainWindow::receiveSig(QVariant varValue){    SRT_STUDENT stu1;    stu1 = varValue.value();    qDebug() << "age=" << stu1.age << "name=" << stu1.name;//age= 20 name= lili}

如此便可以发送一个带结构体的信号了.

注意,如果您打算在队列信号和槽连接或QObject的属性系统中使用该类型(QVariant),您还必须调用qRegisterMetaType(),因为名称是在运行时解析的。即当涉及到线程连接时,在connect之前需要调用qRegisterMetaType()注册此结构体;就像这样使用:

    qRegisterMetaType("SRT_STUDENT"); connect(this,SIGNAL(sig_StudentInfo(QVariant)),this,SLOT(receiveSig(QVariant)));

问题:为什么自定义类型信号槽在跨线程会报错?

因为跨线程时,当发送方信号发出时,此时接受对象所在的线程未取得控制权,所以需要发送方需要将信号放在信号队列中储存发送的参数,QT就会去构造对象,而我们定义的是自定义类型,所以需要使用qRegisterMetaType()来注册,告诉QT怎么去构造对象.