• 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. }

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

  • 相关阅读:
    python threading acquire release
    .net支付宝调试
    C#获取微信openid
    KindeEditor图片上传插件用法
    .net Repeater内部的按钮事件代码demo(Repeater内button的删除事件)
    .net 执行页面跳转弹窗提示,刷新代码
    .net验证控件
    上传图片
    数据库写入时间
    数据库读取
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/14330891.html
Copyright © 2020-2023  润新知