logo头像

技术引领生活!

Qt调用Python并打包发布

本文于890天之前发表,文中内容可能已经过时。

工作中突然遇到 Qt 调用 Python 脚本的情况,研究下并记录填坑记录

必备步骤

  1. 引入头文件和库
  2. 在代码中引入 python.h
  3. 初始化代码,并调用 PyRun_SimpleString 系列函数

新建一个 pri 工程

为啥要弄个 pri 包含呢?这样可以很好的实现代码分离

1
2
3
4
5
6
7
8
9
10
11
INCLUDEPATH += $$PWD

HEADERS += \
$$PWD/callpython.h

SOURCES += \
$$PWD/callpython.cpp

INCLUDEPATH += "c:/python34/include"
LIBS += "c:/python34/libs/python34.lib"

调用示例

1
2
3
4
5
6
7
8
9
10
#include <Python.h>

//.......
{
Py_Initialize(); //初始化

if(!Py_IsInitialized())
return;
PyRun_SimpleString("print('hello python from Qt')");
}

填坑记录

python 和 Qt 的 slot 冲突

  1. 错误为
1
2
3
object.h:435: error: expected unqualified-id before ';' token
PyType_Slot *slots; /* terminated by slot==0. */
^
  1. 解决方法:
  • 方案 1: 避免使用 QObject 及子类
  • 方案 2: 在引用 ptyhon.h 的位置前重新定义 slots,详见文末代码工程
1
2
3
4
//注意人引入位置
#undef slots
#include <Python.h>
#define slots Q_SLOTS
  • 方案 3: 网上一般做法修改 python 的头文件(不推荐)

打包后运行崩溃

  1. 崩溃为
1
Fatal Python error: Py_Initialize: unable to load the file system codec ImportError: No module named 'encodings'
  1. 经过一阵乱撸想到以前用pyinstaller发布程序明明可以不需要 python 环境啊,经测试可行的方法为:
    • 先随便写个.py 代码,使用 pyinstaller 发布
      1
      pyinstaller test.py
  • 拷贝 dist 目录下得所有文件到要打包 qt 的目录下
  • 将 base_library.zip 解压到要打包的 qt 目录下
    不崩溃了
  1. 继续报错
1
2
Failed to import the site module
ImportError: No module named 'site'

搜索 site.py 文件也放到 qt 打包目录下,打完收招

示例工程

文末还是给出示例工程,外加打包好的程序哦代码和可执行程序

支付宝打赏 微信打赏

您的支持是我前行的动力!