QT与Python混合编程经验记录

1、如何embedding python,Python文档中有专门一章阐述https://docs.python.org/3.5/extending/embedding.htm;

1、库文件:在vs--c/c++--附加包含文件中添加目;链接中也要添加,:将python中的include,libs二个目录添加进来

2、对于Python,没有调试库,可直接将运行库复制一份,名称后面加上_d,就可用,可不能源代码调试而已,同时修改

pyconfig.h

#ifdef _DEBUG 
//# define Py_DEBUG    //将这行注释掉
#endif 

和object.h

#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS) 
// #define Py_TRACE_REFS   //将这行注释掉
#endif

3、由于QT中定义了slots作为关键了,而python3中有使用slot作为变量,所以有冲突,办法是:

  A、在vs中-属性-c/c++ -预处理器-预处理器定义-中添加:QT_NO_KEYWORDS指令,

    在Dt的项目文件中.pro文件中添加 config +=_no_keywords指令,再生成vs的项目文件,也就自动添加了上面的指令

    这种方法是全局的,同时也取消 forever,foreach的宏定义,因为很多代码使用foreach,所以副作用大;

  B、在使用第三方代码时暂时取消冲突的宏定义,然后重新定义相关宏,如QT调用第三方python时,只是在python的object.h中 slots冲突,因此修改object.h:

   typedef struct{     

      const char* name;     

      int basicsize;    

       int itemsize;     

      unsigned int flags;

      #undef slots     //这里取消slots宏定义

       PyType_Slot *slots;  /* terminated by slot==0. */

      #define slots Q_SLOTS  //这里恢复slots宏定义与QT中QObjectDefs.h中一致

  } PyType_Spec;  

4、在主程序中执行一开始Py_Initialize(); 时就出现错误

   解决办法是:Py_SetPythonHome((wchar_t*)(L"C:\\Python3"));
是因为我安装python的时候没有添加PYTHONHOME这个环境变量
在Py_Initialize()之前调用下Py_SetPythonHome("C:\\Python3");就可以了 

5、用于导入sys模块,以供程序使用,这是基本模块
PyRun_SimpleString("import sys");

6、在执行pModule = PyImport_ImportModule("jptest"); 语句导入自定义模块时,返回对pModule为NULL,是由于自定义模块的位置不在python系统搜索的系统目录列表内,因此解决办法是在系统搜索目录列表中添加目录:

PyRun_SimpleString("sys.path.append('D:\\develop\\qtpythontest\\Win32\\Debug')");

注意字符中中"\"必须前面加上“\\",也就是单个"\"是转意符;而且目录尾部不能添加多余的\符;如果不能确认可将它们显示出来用下面这个语句:PyRun_SimpleString("print(sys.path)");

7、数据转换,在c/c++与python交互时,都是通过PyObject来传入和传出数据的,Python提供相关函数对PyObject数据进行转换,转换时使用格式字符串来控制生成的对象类型,具体可参见https://docs.python.org/3.5/c-api/arg.html官方文档:

  A) 将c/c++数据转换成PyObject:

    PyObject *pInt=Py_BuildValue("i",2003);

    PyObject *pStr=Py_BuildValue("s","This is a string");

    PyObject *pTuples=Py_BuildValue("()"); //生成空元组,可作为调用不包含任何参数的函数时,传递空参数

    PyObject *pTuples=Py_BuildValue("(s)","This is a string");  //生成一个元素的元组,可作为调用只包含一个字符参数的函数时,传递一个字符参数

  B) 将PyObject数据转换成c/c++数据:

    1) int bb=0;  PyArg_Parse(pObjcet,"i",&bb);   //这里pObject是包含整数数据的Python对象,第二个字符串参数"i"指定转换类型,第三个参数将结果值存入bb变量;

    2) char * cc=NULL;  PyArg_parse(pObject,"s",&cc);   //这是字符串转换

    3) char * cc=NULL;  PyArg_parse(pObject,"(s)",&cc);   //这是包含一个字符串元素元组转换

 

8、调用Python模块函数时,传入参数时,要构造一个参数元组,如:presult = PyObject_CallObject(pfunction, args);这里args就是一个元组,作为被调用函数的参数列表;

  A、如参数为空,则这样构造:args=Py_BuildValues("(si)","abc",10);  表示构造二个参数的元组,一个是字符型,另一个是整;多个参数,可参照处;

  B、如果参数为空,则需构造一个包含0个元素元组:args=Py_BuildValues("()"); 

  注意以上二种都在格式字符串中包含"()",这是指示构造元;作为函数调用参数必须传递元组,也必须这样构;

  下例是通过可变参数来构造调用函数参数元组:

int PythonHandler::PyModuleRunFunction(const char *module, const char *function,
        const char *result_format, void *result, const char *args_format, ...) {
......
    //这里构造调用函数所使用的参数元组

    va_list args_list; va_start(args_list, args_format); args = Py_VaBuildValue(const_cast<char *>(args_format), args_list); va_end(args_list);
  ...
  if (!args)
	{
        //args为空,则元组构造失败 Py_DECREF(pfunction); return -3; } ... presult = PyObject_CallObject(pfunction,args); //调用函数
 
 
 
 

 

转载于:https://www.cnblogs.com/jiaping/p/6321859.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的应用程序开发框架,常用于C++开发。Python是一种动态类型的脚本语言。混合编程指的是在一个项目中同时使用Qt/C++Python进行开发。 混合编程的好处是可以充分发挥QtPython各自的优势。Qt/C++可以提供高性能和可靠性,适用于底层开发和系统级编程Python则提供了简洁易懂、高效编程以及大量的第三方库,适用于快速开发和原型设计。 混合编程的打包过程可以分为以下几个步骤: 首先,需要安装相应的编译工具和开发环境,如QtC++编译器和Python解释器。确定使用的Qt版本与Python版本兼容。 其次,需要为C++部分编写Qt代码,并将其编译成dll或so动态链接库,以供Python调用。这需要使用Qt提供的相关工具和库进行编译和链接。 然后,使用Python的相关库(如PyQt或PySide)来调用C++部分的Qt代码,并将其与Python代码结合起来。这样,就可以实现Qt界面与Python逻辑的交互。 最后,将项目打包成可执行文件、二进制文件或安装包。这可以使用Qt提供的打包工具,如Qt Installer Framework,或者使用第三方工具和脚本来完成。 需要注意的是,在混合编程和打包过程中,需要仔细处理Qt的信号与槽机制与Python的回调机制之间的交互,以确保二者能够正常工作。 总之,Qt C++Python混合编程可以充分利用两者的优势,打包则需要注意兼容性和交互的处理。这种方式可以更灵活地开发应用程序,并能够适应不同的需求和平台。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值