参考: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的则我选择的编译器是
2.2.在qt项目中添加py文件
2.4. 双击.pro文件,添加Python的头文件和库文件
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作为关键字,所以冲突了,再次编译该问题就没有了
解决办法:简单粗暴,直接注释掉
错误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.运行
本人已经完全执行成功了,并得到了正确结果.