Qt5使用C++调python问题总结

 最近在用Qt写桌面应用程序时,有一个模块需要用C++调之前写好的python代码,总结一下自己这段血泪史,也让后来人少走点弯路。

    Qt版本5.10.1 

    编译器mingw530 32位(注意5.10官方发布的编译器只有32位版,好坑)

    python版本3.6.5 32位

下面说明需要注意的几点:

1.需要在.pro文件中加入这两行代码,将.h头文件及lib库包含进去,在调用python程序的cpp文件中也要将头文件包含进去

 

2.object.h中出现有关slot的错误,是因为slot是Qt中的关键字引发的冲突

 

 #undef slots

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

#define slots Q_SLOTS

前后加上这两句话就OK

 

3.出现类似undefined reference to '_imp_Py_XXX'之类的问题

首先保证编译器与python解释器位数一致,因为如果用的是Qt自带的mingw编译器,5.10版本官方仅提供32位,而很多人使用的python都是64位版,因此会报这类的错误,解决办法是去python官网下载32位版,之后将.pro中导入python.h与lib库的路径修改为32位版的路径,并修改有关python的环境变量,令Path与PATHONPATH指向32位版的路径,还有第三方库也应更换为32位版,方法很简单,修改环境变量指向32位版的pip,然后pip install XXX就OK了

 

4.如果解决以上问题.exe程序多半能启动,但是执行调用python的模块时软件多半会崩掉,在debug目录下点击exe文件,操作系统会报0xc000007b,此时有两种可能

    1.OS本身缺少某些dll

    解决办法:下载directX,进行修复,补齐缺少的dll

    2.某些DLL位数不一致,例如应用程序中使用的dll支持的CPU是X86的,而其中混进了amd64的dll,也会报类似错误

    解决办法:下载Dependency Walker检测,更换位数不一致的dll即可

 

5.程序不会崩掉,但是执行调用python的代码时会报有关线程的错误,类似这种

   解决办法是开启一条新的线程去调python,其中牵扯到的问题比较多,这里直接粘源码给大家借鉴吧

 

class PyThreadStateLock
{
public:
    PyThreadStateLock(void)
    {
        state = PyGILState_Ensure( );
    }
 
    ~PyThreadStateLock(void)
    {
         PyGILState_Release( state );
    }
private:
    PyGILState_STATE state;
};
 
class MyThread:public QThread{
public:
    void run();
};
 
void MyThread::run(){
 
    class PyThreadStateLock PyThreadLock;
    PyObject* pModule = PyImport_ImportModule("invoice");
    PyObject* pFun = PyObject_GetAttrString(pModule, "update_data");
    PyObject* pArg = Py_BuildValue("(s)", "F:/pictures");
    PyObject* pRet = PyObject_CallObject(pFun, pArg);
    int res = PyLong_AsLong(pRet);
    qDebug()<<res;
}
 
void Dialog::on_pushButton_clicked()
{   
//    QString path = ui->textBrowser->toPlainText();
 
    Py_Initialize();
    PyEval_InitThreads();
    Py_DECREF(PyImport_ImportModule("threading"));
    PyEval_ReleaseThread(PyThreadState_Get());
 
    MyThread pThread;
    pThread.start();
    pThread.wait();
 
    PyGILState_Ensure();
    Py_Finalize();
 
    hint h;
    h.exec();
}
 

6.注意参数的传递,如果模块以及函数的导入没有问题,程序却调不起来,多半是执行

PyObject_CallObject

时参数传递有问题,好好检查参数的数据类型吧。。。

 

7.如果上述问题全部解决却还是无法正确调用

建议在命令行模式下执行下需要调用的py文件,看会报什么错误

因为有些类似编解码的问题pycharm等IDE是不会报错的,但是DOS中会!!!

 

以上

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值