随笔 - 741  文章 - 0  评论 - 260  阅读 - 416万

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   莫水千流  阅读(3121)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示