Ctypes简单应用以及PyQt5等简单使用过程中遇到的部分问题

最近接到了个需求,需要在linux下做一个demo,对接公司自己的so,此so负责节点通讯等功能,前台的demo负责界面呈现。

此软件为CS架构,上文提到的动态库,负责与服务器之间的通讯,对上层UI只提供初始化等基本接口,通过回调函数,利用字符串形式xml与UI进行交互。

我所在的小组平时负责通讯平台部分,即节点通讯与基础数据管理(实体信息cache)等。

之前做过一段时间的wpf,这次要做linux下的界面demo一开始有点没思路,查了下资料,QT是个不错的选择。

说干就干,正好前阵子看了看python,所以这次开发选了PyQt5。

确定的方案之后做了一下几件事:

  1.搭建环境(ubuntu16.04,python3.6,pycharm2017.3.3,PyQt5)

  2.寻找python调用so的解决方案(Ctypes)

  3.理解基本的QT编程(其实最后也没怎么看,pyUI 很简单生成py文件之后,直接继承下,直接就能实现界面与逻辑的分离,的确挺好用,不过UI的复杂设计没有看太多)

总体下来还算顺利,排坑大概用了有效时间两天。

  主要遇到的问题:

  1.pycharm中引用PyQt5 提示 No moudle named ‘PyQt5’,但是在vsCode和命令行中正常,最终的发现是pyCharm的解释器环境问题,pyCharm会默认搭建venv把python环境复制出来一份,但是site-packages并不会复制,导致了却上相应扩展包

    解决:Setting->Project Interpreter (解释器)中选择 Add Local... (点击右上方解释器右侧的小齿轮),添加existing environment 把本机中已经安装的python路径输入 选择python.exe 即可。

  2.ctypes类库的使用

    主要是两个问题,1.结构体的传递  2.函数指针的传递。

    最终的解决:

python

import sys, os
from ctypes import *

CMPFUNC = CFUNCTYPE(None,c_wchar_p)#第一个参数为返回值,其余为参数列表 一开始这个地方没看懂,费了点时间才搞清楚

def py_cmp_func_onResponse(Str):
    print(Str)

class InitAPIData(Structure):
    _fields_ = [
        ("_responseback", CFUNCTYPE(None,c_wchar_p)),
        ("_strLocalLocalSipIP", c_wchar_p),
        ("_nlocalSipPort", c_int),
    ]
initData = InitAPIData(CMPFUNC(py_cmp_func_onResponse),'strForTest',93424)


libtest = cdll.LoadLibrary(d)
libtest.test_a()
libtest.test_b(byref(initData))
print('end')

  

测试so部分的测试文件:.h头文件

#include <stdio.h>
#ifdef __cplusplus
extern "C"{


typedef wchar_t WCHAR;

typedef WCHAR TCHAR;


typedef void(* OnResponse)(TCHAR*);


typedef struct InitAPIData_t{
	

	OnResponse _responseback;//call back

	TCHAR* _strLocalLocalSipIP;//local sip ip

	int _nlocalSipPort;//local sip port

}InitAPIData;


void test_a();

void test_b(InitAPIData *pdata);
}
#endif

  cpp文件

#include "so_test.h"
#include <iostream>

using namespace std;

void test_a(){

        printf("this is test_a ...\n");

}

void test_b(InitAPIData *pdata){
	
	//std::string s1 = pdata->_strLocalLocalSipIP;
	//std::cout << "str1 :"<<*(pdata->_strLocalLocalSipIP)<<std::endl;

	const wchar_t * txt = pdata -> _strLocalLocalSipIP;
	wstring ws(txt);

	string str(ws.begin(), ws.end());
	
	std::cout <<"str: "<<str<<std::endl;
	
	const char* t1  = "1234";
	pdata->_responseback((TCHAR*)txt);

	std::cout <<"Port: "<<pdata -> _nlocalSipPort <<std::endl;	
	
	std::cout<<"pdata -> _nlocalSipPort: "<<pdata->_nlocalSipPort<<std::endl;
	
}

  附上官网参考文献地址:https://docs.python.org/2/library/ctypes.html

  3.其他   

    再就是qt部分看了下生成的UI文件,感觉总体上还是比较好理解的,界面与业务的分离也很好处理,特效方面没怎么看只是拖了几个控件,弄了下前后台的交互。另外重新开始看下linux 毕业之后看的不多,太多东西要学了,还得恶补下。对了,

  环境搭建方面建议除了pycharm全部pip 或者 apt-get  解决问题,很简便。

转载于:https://www.cnblogs.com/xiapuxiaohei/p/8399255.html

### 如何在 PyQt5 中设置任务栏图标 为了确保应用程序的任务栏图标能够正常显示,在 PyQt5 应用程序中可以通过多种方式实现这一功能。 #### 使用 `setWindowIcon()` 方法 对于大多数情况而言,仅需调用 `setWindowIcon()` 即可完成操作。此方法接收一个 QIcon 对象作为参数,并将其应用于整个应用程序窗口及其子部件[^1]: ```python from PyQt5.QtWidgets import QApplication, QMainWindow import sys app = QApplication(sys.argv) main_window = QMainWindow() main_window.setWindowTitle('Example Application') main_window.setWindowIcon(QIcon('path/to/icon.png')) # 设置窗口图标同时也会影响任务栏图标 main_window.show() sys.exit(app.exec_()) ``` 然而,在某些操作系统环境下(如特定版本的 Windows),可能会遇到任务栏图标未能正确更新的情况。此时可能需要采取额外措施来强制刷新或重新注册应用程序图标[^4]。 #### 利用 `ctypes` 修改 AppUserModelID (针对 Windows 平台) 如果上述简单的方法无法解决问题,则可以尝试利用 Python 的内置模块 `ctypes` 来修改当前进程的应用模型 ID(AppUserModelID),这有助于解决一些特殊情况下任务栏图标未按预期显示的问题[^2]: ```python import ctypes myappid = 'your_company.your_product.subproduct.version' # 定义唯一的AppUserModelID字符串 ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) ``` 这段代码应该放置于创建主窗口之前执行,以便让更改生效并影响后续创建的所有窗口实例。 另外值得注意的是,当处理不同平台时应考虑兼容性问题;而对于 Linux 或 macOS 用户来说,通常不需要特别调整即可获得理想的效果[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值