Qt与C语言交互探讨

0、背景

界面线程由Qt实现,底层数据处理主要由C语言实现,此时CQt的数据交互不可避免。

 

1.1、Qt信号与槽

 

使用信号与槽的机制进行CQt的多线程通信。

1、定义一个用于发射信号的类SysCourier,并创建其对象sysCourier

2、把该对象aQt的界面对象使用connect连接相应的信号与槽

3、在cpp文件中,定义全局函数,该全局函数调用对象a的函数发射信号

4、在头文件中使用extern “C” 的方法声明创建的全局函数。

该法相对直接读取全局变量、函数较为繁琐,但避免了多线程造成的数据混乱,且在某些时候具有更好的优势,下面将讲述 )

例子如下:

SysCourier头文件SysCourier.h

<span style="font-size:14px;">#ifndef SYSCOURIER_H
#define SYSCOURIER_H
#include <QObject>
class SysCourier : public QObject
{
    Q_OBJECT
public:
explicit SysCourier(QObject *parent = 0);
/*
 CPP文件的全局函数通过sysCourier调用此函数,发射信号 
  sg_updateInfo(int arg,  	const char * msg);
*/
    void    	comUpdateInfo(int arg, const char * msg);
signals:
    void 	sg_updateInfo(int arg, const char * msg);
};
extern SysCourier *sysCourier;	//声明通信类对象的指针,让包含该头文件的CPP文件可访问该对象

#endif // SYSCOURIER_H</span>


 

SysCourier源文件SysCourier.cpp

<span style="font-size:14px;">#include "syscourier.h"

SysCourier::SysCourier(QObject *parent) :
    QObject(parent)
{
}
void SysCourier::comUpdateInfo(int arg, const char * msg)
{
    Q_EMIT(sg_updateInfo(arg, msg));
}</span>

 

C语言文件调用的C++函数接口,头文件 c2qt.h

<span style="font-size:14px;">#ifndef COMBYQT_H
#define COMBYQT_H

#ifdef __cplusplus	//使用该宏,使该文件按c的方式去编译,这样c文件就可
extern "C"			//调用此文件描述的函数声明
{
#endif
    extern void update_sys_startinfo(int arg,  const char *msg);
#ifdef __cplusplus
}
#endif
#endif // COMBYQT_H</span>


 

对应的源文件 c2qt.cpp

<span style="font-size:14px;">#include <QSettings>
#include <QDebug>
#include "c2qt.h"
extern "C"
{
    static char buf[64];//定义一个静态内存区,存放临时通信数据,防止传入的指针未被Qt使用就在C语言的线程中释放
    void update_sys_startinfo(int arg, const char *msg)
    {
        strcpy(buf, msg);//数据存入临时内存区
 //发射信号
        sysCourier->comUpdateStartInfo(arg, buf);
    }
}</span>

 

1.2Qt事件机制

1.3、直接使用全局变量、全局函数

1)、Qt引用C的全局变量、函数:直接引用即可

2)、C引用Qt的全局变量、函数,需使用extern “C”的宏编译方法

 

1.4、方法对比

对于上述通信办法,应根据业务需求作出合适的选择。我认为可以分为两种类型:

1)、被动需求:(被需要)

如:底层某个状态变量发生变化时,需在界面中体现出来,Qt可以通过定时器或循环阻塞轮询读取该状态变量是否发生变化,但此法消耗量大,反应亦不一定迅速,故性价比低。此时即可使用Qt信号与槽的机制或事件机制。

2)、主动需求:

如:底层线程在运行过程需要获取界面某个变量或结构,最简单的办法是直接读取该值(该结构定义为全局或通过全局函数返回该结构),同理,界面线程在运行过程需要用到某个结构值时,也可直接读取。

 


 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值