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

当发送的信号是结构体时

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

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

最后一步:连接信号.

具体实例如下:

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include<QVariant>

struct 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 <QDebug>

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<SRT_STUDENT>();
    qDebug() << "age=" << stu1.age << "name=" << stu1.name;//age= 20 name= lili
}




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

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

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

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

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

或许你会感兴趣!!!

QMetaObject::invokeMethod()使用解决界面卡住问题

  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Qt 中,发送结构体数据信号需要注意以下几点: 1. 结构体必须在信号所在的头文件中定义。 2. 结构体必须是 Qt 可识别的数据类型,即需要使用 Q_DECLARE_METATYPE 宏声明该结构体类型。 3. 在发送信号时需要使用 QVariant 类型对结构体进行封装。 下面是一个简单的示例代码: ```cpp // MyStruct.h #ifndef MYSTRUCT_H #define MYSTRUCT_H #include <QString> struct MyStruct { QString name; int age; }; #endif // MYSTRUCT_H // MyThread.h #ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> #include "MyStruct.h" class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); signals: void sendStruct(const QVariant &data); protected: void run() override; }; #endif // MYTHREAD_H // MyThread.cpp #include "MyThread.h" #include <QMetaType> MyThread::MyThread(QObject *parent) : QThread(parent) { // 注册 MyStruct 类型 qRegisterMetaType<MyStruct>("MyStruct"); } void MyThread::run() { MyStruct data; data.name = "Tom"; data.age = 18; // 将结构体数据封装为 QVariant 类型并发送信号 emit sendStruct(QVariant::fromValue(data)); } // MainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "MyStruct.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void handleStruct(const QVariant &data); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H // MainWindow.cpp #include "MainWindow.h" #include "ui_MainWindow.h" #include "MyThread.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 注册 MyStruct 类型 qRegisterMetaType<MyStruct>("MyStruct"); MyThread *thread = new MyThread(this); connect(thread, &MyThread::sendStruct, this, &MainWindow::handleStruct); thread->start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::handleStruct(const QVariant &data) { // 从 QVariant 类型中获取 MyStruct 数据 MyStruct myStruct = data.value<MyStruct>(); ui->label->setText(QString("%1 %2").arg(myStruct.name).arg(myStruct.age)); } ``` 在这个示例中,我们在 MyStruct.h 中定义了一个简单的结构体 MyStruct,然后在 MyThread 类中使用 QVariant 类型对该结构体进行封装并通过 sendStruct 信号发送出去。在 MainWindow 类中,我们定义了一个 handleStruct 槽函数来接收信号并从 QVariant 类型中获取 MyStruct 数据,最后将其显示在 UI 上。注意,我们在 MainWindow 和 MyThread 中都使用了 qRegisterMetaType<MyStruct>("MyStruct") 来注册 MyStruct 类型,以便 Qt 可以识别该类型。 希望这个示例对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鱼2333号程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值