QT信号槽传递自定义结构体

QT的信号槽可以传递int, short, double等c语言的常用类型的变量,也可以传递如QImage之类的QT支持 的类型。但是如何传递一个程序员自定义的结构体?

1)在定义结构体之后,要调用Q_DECLARE_METATYPE,向QT声明这个结构体

2)在main.cpp 中,用connect函数 将抛出此结构体的信号和接收此结构体的槽函数关联之前,要调用qRegisterMetaType()注册此结构体

看下面例子 ,在专门定义结构体的头文件里调用Q_DECLARE_METATYPE

  1. #ifndef PROTOCOL_H
  2. #define PROTOCOL_H
  3.  
  4. #include <QMetaType>
  5.  
  6. #pragma pack(push, 1)
  7.  
  8. #if !defined(DEF_ST_ARB_STRUCT)
  9. typedef struct ST_ARB_STRUCT
  10. {
  11. double d;
  12. int i;
  13. char c;
  14. } ST_ARB_STRUCT;
  15. #define DEF_ST_ARB_STRUCT
  16.  
  17. Q_DECLARE_METATYPE(ST_ARB_STRUCT);
  18. //qRegisterMetaType<ST_ARB_STRUCT>();
  19. #endif
  20.  
  21. #pragma pack(pop)
  22. #endif // PROTOCOL_H
  23.  

定义类ArbStruct,负责向另一个类发射含有(ST_ARB_STRUCT)的信号sigArbStruct(ST_ARB_STRUCT)

  1. #ifndef ARBSTRUCT_H
  2. #define ARBSTRUCT_H
  3.  
  4. #include "protocol.h"
  5. #include <QObject>
  6.  
  7. class ArbStruct : public QObject
  8. {
  9. Q_OBJECT
  10. public:
  11. ArbStruct();
  12.  
  13. signals:
  14. void sigArbStruct(ST_ARB_STRUCT);
  15.  
  16. public slots:
  17. void OnRecvEmit(void);
  18. };
  19.  
  20. #endif // ARBSTRUCT_H

特别地,这个类ArbStruct被封装为一个lib库,为的是证明即使发射信号的类的定义跟接收方的定义并不处于同一个项目里,信号槽仍然可以走通。

  1. #include "arbstruct.h"
  2.  
  3.  
  4. ArbStruct::ArbStruct()
  5. {
  6. }
  7.  
  8. void ArbStruct::OnRecvEmit(void)
  9. {
  10. ST_ARB_STRUCT stMsg;
  11. stMsg.d = 6.5;
  12. stMsg.c = 0;
  13. stMsg.i = -1;
  14.  
  15. emit sigArbStruct(stMsg);
  16. }

在主工程里定义另一个类,负责接收sigArbStruct(ST_ARB_STRUCT)

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3.  
  4. #include <QMainWindow>
  5. #include "protocol.h"
  6.  
  7. namespace Ui {
  8. class MainWindow;
  9. }
  10.  
  11. class MainWindow : public QMainWindow
  12. {
  13. Q_OBJECT
  14.  
  15. public:
  16. explicit MainWindow(QWidget *parent = 0);
  17. ~MainWindow();
  18. signals:
  19. void sigClicked(void);
  20. public slots:
  21. void OnRecvArbStruct(ST_ARB_STRUCT);
  22. private:
  23. Ui::MainWindow *ui;
  24. };
  25.  
  26. #endif // MAINWINDOW_H

接收到ArbStruct发来的信号后,MainWindow将把信号内的数据显示在界面上

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3.  
  4. MainWindow::MainWindow(QWidget *parent) :
  5. QMainWindow(parent),
  6. ui(new Ui::MainWindow)
  7. {
  8. ui->setupUi(this);
  9. connect(ui->pushButton, SIGNAL(clicked()), this, SIGNAL(sigClicked()));
  10. }
  11.  
  12. MainWindow::~MainWindow()
  13. {
  14. delete ui;
  15. }
  16.  
  17. void MainWindow::OnRecvArbStruct(ST_ARB_STRUCT stMsg)
  18. {
  19. ui->label->setText(QString("d = %1, i = %2, c = %3")
  20. .arg(stMsg.d).arg(stMsg.i).arg(int(stMsg.c)));
  21. }

最后在main.cpp里联系两个类,注意用了qRegisterMetaType:

  1. #include "mainwindow.h"
  2. #include <QApplication>
  3. #include "protocol.h"
  4. #include "arbstruct.h"
  5.  
  6. #pragma comment(lib, "ArbStruct.lib")
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10. QApplication a(argc, argv);
  11.  
  12. ArbStruct arb;
  13. MainWindow w;
  14.  
  15. qRegisterMetaType<ST_ARB_STRUCT>("ST_ARB_STRUCT");
  16. QObject::connect(&arb, SIGNAL(sigArbStruct(ST_ARB_STRUCT)), &w, SLOT(OnRecvArbStruct(ST_ARB_STRUCT)));
  17. QObject::connect(&w, SIGNAL(sigClicked()), &arb, SLOT(OnRecvEmit()));
  18. w.show();
  19.  
  20. return a.exec();
  21. }

本示例可以在我的资源中下载

posted on 2021-01-26 16:05  莫水千流  阅读(2975)  评论(0编辑  收藏  举报