如何在QT信号中传递结构体或者复杂数据类型
1. 传递复杂类型的方法
关于传递复杂数据类型QT内部提供了一组宏:
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(Container)
Q_DECLARE_METATYPE(Type)
Q_DECLARE_OPAQUE_POINTER(PointerType)
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(Container)
Q_DECLARE_SMART_POINTER_METATYPE(SmartPointer)
2. Q_DECLARE_METATYPE(Type)使用说明
以信号和槽函数传递结构体为例:
假设我们现在有这样一种需求:点击界面一个Button, A类中的结构体数据需要通过信号和槽传递给B类。
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMetaType>
#include <QVariant>
namespace Ui {
class Widget;
}
struct Student
{
int m_age;
char m_Name[32];
};
struct Packet
{
int m_id;
Student m_stInfo[3];
bool m_blRecord;
};
// 注册元对象
Q_DECLARE_METATYPE(Packet)
class CTest;
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void SlotButtonClick(bool);
signals:
void SigParamUpdate(int param, const QVariant varValue);
private:
Ui::Widget *ui;
CTest *m_pTest;
};
class CTest:public QObject
{
Q_OBJECT
public:
CTest():m_blRecord(false){}
~CTest(){}
public slots:
void SlotParamUpdate(int param, const QVariant varValue);
private:
bool m_blRecord;
QString m_strName;
};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget),
m_pTest(new CTest)
{
ui->setupUi(this);
connect(this, SIGNAL(SigParamUpdate(int,QVariant)),
m_pTest, SLOT(SlotParamUpdate(int,QVariant)));
connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(SlotButtonClick(bool)));
}
Widget::~Widget()
{
delete ui;
delete m_pTest;
}
void Widget::SlotButtonClick(bool)
{
Packet iPackInfo;
memset(&iPackInfo, 0, sizeof(iPackInfo));
iPackInfo.m_id = 1;
iPackInfo.m_stInfo[1].m_age = 22;
char *name = "DDZ";
int length = sizeof(iPackInfo.m_stInfo[0].m_Name)/sizeof(*iPackInfo.m_stInfo[0].m_Name);
for(int i= 0; i < 3; i++)
{
memset(iPackInfo.m_stInfo[i].m_Name, 0, length);
memcpy(iPackInfo.m_stInfo[i].m_Name, name, strlen(name));
}
iPackInfo.m_blRecord = true;
QVariant varValue = QVariant::fromValue(iPackInfo);
emit SigParamUpdate(1, varValue);
}
void CTest::SlotParamUpdate(int param, const QVariant varValue)
{
qDebug()<<"param: "<<param;
if (varValue.canConvert<Packet>())
{
Packet PacketInfo = varValue.value<Packet>();
m_blRecord = PacketInfo.m_blRecord;
m_strName = QString(PacketInfo.m_stInfo[param].m_Name);
}
qDebug()<<"m_strName: "<< m_strName;
qDebug()<<"m_blRecord: "<< m_blRecord;
}
测试结果,点击界面Button后,在CTest类中可以接受到另外一个类发送的信息:
param: 1
m_strName: “DDZ”
m_blRecord: true
3. 主要步骤
-
注册元对象 Q_DECLARE_METATYPE(T)
-
注意QVariant的赋值 QVariant varValue = QVariant::fromValue(T);
-
注意槽函数中取值的方法
if (varValue.canConvert<T>())
{
T obj = varValue.value<T>();
...
}