zoukankan      html  css  js  c++  java
  • 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); //调用函数
    
    
    
    
    
  • 相关阅读:
    CSS3—— 2D转换 3D转换 过渡 动画
    CSS3——边框 圆角 背景 渐变 文本效果
    CSS3——表单 计数器 网页布局 应用实例
    CSS3——提示工具 图片廓 图像透明 图像拼接技术 媒体类型 属性选择器
    CSS3——对齐 组合选择符 伪类 伪元素 导航栏 下拉菜单
    CSS3——分组和嵌套 尺寸 display显示 position定位 overflow float浮动
    CSS3——盒子模型 border(边框) 轮廓(outline)属性 margin外边距 padding填充
    Eclipse连接数据库报错Local variable passwd defined in an enclosing scope must be final or effectively final
    数据库——单表查询
    数据库——添加,修改,删除
  • 原文地址:https://www.cnblogs.com/jiaping/p/6321859.html
Copyright © 2011-2022 走看看