PYQT5接收自定义windows消息
遇到的问题
python调用Dll文件里的函数,调用后会从函数中发出自定义windows信号,在pyqt5界面中获取信号中包含的数据(数据的格式为结构体)
解决方案
pyqt自带的nativeEvent函数
1. 定义结构体
第一步,根据DLL文件的文档或者源码,定义需要获取的结构体,我这里是根据文档
(1)文档内容如下
typedef struct tagTemperature
{
int type;
int number;
int temper;
}_tagTemperature;
typedef struct tagTempHandle
{
int handle;
int len;
}_tagTempHandle;
(2)在python中进行重定义
class tagTemperature(Structure):
_fields_ = [
("type", c_int),
("number", c_int),
("temper", c_int)
]
class tagTempHandle(Structure):
_fields_ = [
("handle", c_int),
("len", c_int)
]
2. 定义自定义windows消息
第二步,根据DLL文件的文档或者源码,定义自定义windows消息,消息里包含wParam和LParam两部分数据(都是结构体格式),我这里是根据文档
(1)文档内容如下
#define WM_DM_TEMP_VALUE (WM_APP + 0x3053)
//wParam 温度消息内容
//lParam 设备句柄
//实时温度消息
(2)在python中进行重定义
WM_DM_TEMP_VALUE = win32con.WM_APP + 0x3053
3. 消息的发送
第三步,发送消息,调用dll函数,函数自动发送消息,因为我使用的是别人提供的封装好的DLL,所以没有发送消息的源码
首先,需要先引用DLL文件,再对函数进行封装,将dll文件中的函数封装成python函数,最后在界面中进行调用
代码如下:
class DMSDK(object):
def __init__(self):
self.CUR_PATH = os.path.dirname(__file__)
self.dllPath = os.path.join(self.CUR_PATH + "/DMSDK_V1.16", "DMSDK")
# 以__stdcall定义的函数用WinDLL来读取
self.pDLL = WinDLL(self.dllPath) # 引用
# 封装
def myDM_GetTemp(self, handle, Mode):
'''
获取所有测温目标的测温结果
:param handle:句柄
:param Mode:0:返回一次温度
1:连续返回温度,间隔时间由仪器自动调节。
:return:>0 成功
接收返回的数据在消息WM_DM_TEMP_VALUE中处理
'''
GetTemp = self.pDLL.DM_GetTemp # dll中的函数
result = GetTemp(c_int(handle), c_int(Mode))
return result
#在界面类中进行调用
def Test_Btn_click(self):
result = self.dm_SDK.myDM_GetTemp(self.connectHandle, 0) # 封装后的函数
print(result)
4. 消息的接收
最后,在nativeEvent函数中接收发送的消息
def nativeEvent(self, eventType, message): # 固定的写法
mess = ctypes.wintypes.MSG.from_address(message.__int__())
if mess.message == WM_DM_TEMP_VALUE:
TempHandleStruct = ctypes.POINTER(tagTempHandle)
TempHandle = ctypes.cast(mess.lParam, TempHandleStruct)
handle = TempHandle.contents.handle # 句柄
len = TempHandle.contents.len # 有几组温度数据
print(handle, len)
tempStruct = ctypes.POINTER(tagTemperature)
temp = ctypes.cast(mess.wParam, tempStruct)
type = temp.contents.type # 类型
number = temp.contents.number # 编号
temper = temp.contents.temper # 温度
print(type, number, temper)
return False, 0
参考资料:
https://blog.csdn.net/weixin_41619611/article/details/103070939
https://segmentfault.com/a/1190000013339754