提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
Python在数据分析和交互、探索性计算以及数据可视化等方面显得比较活跃,也简单易学,因而使用
Python处理数据,C++则调用Python处理的结果,这是一个不错的选着。
本文使用简单示例,演示Qt5调用Python3处理数据编程方法,以及踩坑的问题解决,作为学习入门。
一、Qt5调用Python3示例
软件环境:window10 64-bit、Qt5.12.12(MinGw 64-bit)、Python 3.10.4 64-bit、
1.1. Qt project添加外部Python库
1、Qt Creator右键工程文件夹“QtCallPythonSimpleExample”,选着“添加库”

2、选着库类型为“外部库”,点击“下一步”

3、库文件–选着已安装Python3.10.4的库文件".lib",包含路径–选着Python的"include"头文件路径,选着动态库、windows平台,点击“下一步”

4、最后工程配置文件QtCallPythonSimpleExample.pro会生成如下配置,外部库导入文件
# add external third party library
win32: LIBS += -L$$PWD/../../../../../../software/Python/Python310-4/libs/ -lpython310
INCLUDEPATH += $$PWD/../../../../../../software/Python/Python310-4/include
DEPENDPATH += $$PWD/../../../../../../software/Python/Python310-4/include
1.2. 源代码
1、main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
2、mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtDebug>
#include <Python.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
#define Ways_In_Integrated_API true
int num1 = ui->lineEdit->text().toInt();
int num2 = ui->lineEdit_2->text().toInt();
Py_Initialize();
if(!Py_IsInitialized()) {
qDebug()<<"Python init fail!";
return;
}
PyObject* pModule = PyImport_ImportModule("PySum");
if (nullptr == pModule) {
PyErr_Print(); // print stack, 看看具体是什么错误
qDebug()<<"PyImport_ImportModule 'PySum.py' not found";
return;
}
PyObject* pFunadd = PyObject_GetAttrString(pModule, "add");
if (nullptr == pFunadd) {
PyErr_Print(); // print stack, 看看具体是什么错误
qDebug()<<"PyObject_GetAttrString 'add' not found";
return;
}
#if Ways_In_Integrated_API
PyObject* args = Py_BuildValue("(i,i)", num1, num2);
if (nullptr == args) {
PyErr_Print(); // print stack, 看看具体是什么错误
qDebug()<<"PyTuple_New(2) fail";
return;
}
#else
PyObject* args = PyTuple_New(2);
if (nullptr == args) {
PyErr_Print(); // print stack, 看看具体是什么错误
qDebug()<<"PyTuple_New(2) fail";
return;
}
PyObject* arg1 = Py_BuildValue("i", num1);
PyObject* arg2 = Py_BuildValue("i", num2);
if (nullptr == arg1 || nullptr == arg2) {
PyErr_Print(); // print stack, 看看具体是什么错误
qDebug()<<"Py_BuildValue(\"i\", num1) fail";
return;
}
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
#endif
PyObject *pyValue = PyObject_CallObject(pFunadd, args);
if (nullptr == pyValue) {
PyErr_Print(); // print stack, 看看具体是什么错误
qDebug()<<"PyObject_Call 'add' not found";
return;
}
int iRefVal = 0;
PyArg_Parse(pyValue, "i", &iRefVal);
Py_Finalize();
ui->label_2->setText(QString::number(iRefVal));
}
3、PySum.py
新建Python程序文件,右键工程文件 --> Add New… --> 弹出如下框

# This Python file uses the following encoding: utf-8
# if__name__ == "__main__":
# pass
#!/usr/bin/env/python3
# -*- coding: utf-8 -*-
def add(a, b):
print('a=%d'%a,'b=%d'%b)
return a+b
二、 遇到问题
*1. Python object.h报PyType_Slot slots;error: expected unqualified-id before ‘;’ token错误

原因:slots是QT语言的关键字,跟Python定义的变量名冲突
解决:Python object.h定义前先取消QT slots关键字定义,Python定义完后再恢复QT slots定义
#undef slots /* 1 先取消Qt slots关键字定义 */
typedef struct{
const char* name;
int basicsize;
int itemsize;
unsigned int flags;
PyType_Slot *slots; /* terminated by slot==0. */
} PyType_Spec;
#define slots Q_SLOTS /* 2 Python使用完后,恢复Qt slots关键字定义 */
2. Qt找不到自己定义py文件–PyImport_ImportModule ‘PySum.py’ not found

原因:绝对路径问题。Qt编译构建出来exe执行程序,与Qt代码不在同一个目录下,导致找不到代码中Python程序文件
解决:
(1)工程配置QtCallPythonSimpleExample.pro设定Qt Creator编译构建出来exe程序到当前路径,即与QtCallPythonSimpleExample.pro在同一个路径下
# 指定放置可执行程序目标目录的
DESTDIR = $$PWD

(2)重新配置QtCallPythonSimpleExample的QT构建路径 “Import Build From…”为与QtCallPythonSimpleExample.pro同一路径下

3. Qt5调用Python API:Py_Initialize/Py_IsInitialized,程序异常退出
附录
参考文档:
利用Python进行数据分析
https://seancheney.gitbook.io/python-for-data-analysis-2nd/di-01-zhang-zhun-bei-gong-zuo
本文介绍了如何在Qt5环境下调用Python3进行数据处理,包括在Qt项目中添加Python库、编写源代码实现调用,以及解决遇到的如Python对象头文件冲突、找不到Python模块和初始化异常等问题。通过示例代码详细展示了调用过程,并给出了问题的解决方案。
4648

被折叠的 条评论
为什么被折叠?



