qt&python混合编程

参考:Qt调用Python详细过程_贝勒里恩的博客-CSDN博客_qt python

1.环境搭建

1.1.python3.6 32bits

1.2.qt5.12.12 32bits

说明:

(1).务必保持版本位数一致,没有一致就得重新下载一致的版本

(2).以上软件环境的下载和安装,请自行百度,资料很多,在此重点说说混合编程遇到的错误如何解决.

(3).请装完软件后一定要试一试是否能够正常运行

2.创建工程

2.1.创建qt工程

注意:选择编译器时必须选择和版本对应位数的编译器!如我是用32bits的则我选择的编译器是

qt&python混合编程_第1张图片

2.2.在qt项目中添加py文件

 qt&python混合编程_第2张图片

 2.3.编辑py文件,写入代码:qt&python混合编程_第3张图片

2.4. 双击.pro文件,添加Python的头文件和库文件

qt&python混合编程_第4张图片

INCLUDEPATH += C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\include
LIBS += -LC:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\libs -lpython36
LIBS += -LC:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\libs -lpython36_d
#注意:-L 和 PATH 之间不能有空格

 说明:

(1).请按照个人自己安装的路径作修改

(2)."python36_d.lib"文件是为了qt在debug模式下用的,且这个文件在...Python\Python36-32\libs文件夹中并没有,是我复制了一份python36.lib文件后重命名得到的,如果没有这个文件debug模式下编译会出错

3.功能代码编写

3.1."mainwindow.h"内容

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

3.2."mainwindow.cpp"内容

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Py_Initialize();
    if( !Py_IsInitialized() )
        qDebug()<<"Py_Initialize fail";
    else
        qDebug()<<"Py_Initialize pass";

    //导入sys模块设置模块地址
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");
    //QString setSysPath = QString("sys.path.append('%1')").arg(QCoreApplication::applicationDirPath());
    //PyRun_SimpleString(setSysPath.toStdString().c_str());

    //创建模块指针
    PyObject* pModule = PyImport_ImportModule("Py_Module");
    if (!pModule)
        qDebug()<<"pModule fail";

    //创建函数指针
    PyObject* pFunc= PyObject_GetAttrString(pModule,"add");
    if(!pFunc)
        qDebug()<<"pFunc fail";

    //创建函数参数,方法1
    PyObject* pPara = PyTuple_New(2);        // 2个参数
    PyTuple_SetItem(pPara, 0, Py_BuildValue("i",1));  //参数1为int型 1
    PyTuple_SetItem(pPara, 1, Py_BuildValue("i",2));  //参数2为int型 2

    //创建函数参数,方法2
    PyObject* args = PyTuple_New(2);        // 2个参数
    PyObject* arg1 = PyLong_FromLong(4);    // 参数一设为4
    PyObject* arg2 = PyLong_FromLong(3);    // 参数二设为3
    PyTuple_SetItem(args, 0, arg1);
    PyTuple_SetItem(args, 1, arg2);

    //调用Python函数,传入元组参数pPara
    PyObject *FuncBack = PyObject_CallObject(pFunc,pPara);
    //PyObject_CallObject(pFunc,nullptr); //无参数调用

    //FuncBack是返回值指针,转换获取返回值
    int res = 0;
    PyArg_Parse(FuncBack,"i",&res);
    qDebug()<<"return: "<

4.编译

        会出现以下报错:

4.1.

错误1:找不到Python.h

出现原因: 因为我们在c++中使用这个了头文件,因此出现了找不到python.h
解决办法: 在.pro文件中添加python的头文件以及静态链接库,参考:2.4的内容

错误2

PyType_Slot *slots; object.h(445) : error C2059: 语法错误:“;”
object.h(445) : error C2238: 意外的标记位于“;”之前

解决办法:把slots改成slots1,Python将slots作为变量,而Qt将slots作为关键字,所以冲突了,再次编译该问题就没有了

错误3
qt&python混合编程_第5张图片

解决办法:简单粗暴,直接注释掉

 错误4:

报错信息:

Fatal Python error: Py_Initialize: unable to load the file system codec

ModuleNotFoundError: No module named 'encodings' 

 解决办法:

开发模式下将python目录下的Lib文件夹复制到debug/release目录下;生成exe后将Lib文件夹复制到同级目录下就可以了,这样就完全脱离了python的环境。

错误5:

报错信息:运行时闪退

        这是可能是因为代码执行时产生了异常而终止,如获取模块指针失败就会闪退,请将将工程下的Py_Module.py复制到构建目录下的debug文件夹中,这样EXE文件在执行时才找得到模块. 

其它解决办法:qt编译之后的闪退可能是python36.dll没有放到debug/release目录下

5.运行

本人已经完全执行成功了,并得到了正确结果.

 qt&python混合编程_第6张图片

 

你可能感兴趣的:(qt,qt,python)