1. 安装Python环境

     去python官网下载python安装包,可以根据自己的系统选择对应的安装包。如下图所示:

QT 用python写代码吗 qt可以用python吗_Python

另外在下载安装包时,还需要根据自己编译器的版本选择对应的python版本。因为在安装python的debug环境时,有编译器版本的要求。如果不需要在debug环境下使用,可以直接下载最新版本。如:

QT 用python写代码吗 qt可以用python吗_c++_02

目前,python3.8.10及3.7系列的版本,在windows上需要的vs编译器都是2015及之后的版本。而python3.9.5则要求2017及之后的版本了。

在安装python时,最好将python配置到环境变量中,即勾选上图中的“Add Python to environment variables”。

 

2. 配置C++或Qt开发环境

    我这里是在Windows上用qt creator开发的。

2.1. 创建工程

    使用qt creator创建一个plain c++工程,命名为cpython。

2.2. 配置工程

    打开cpython.pro文件,将python的头文件目录和库目录配置进去。如:

TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += \
        main.cpp

INCLUDEPATH += C:\Python\Python37\include

LIBS += -LC:\Python\Python37\libs  -lpython37

保存文件,然后执行qmake。看配置的目录是否能够正常被qt creator找到。

3. 调用python

3.1. 创建python脚本文件

   可以直接使用qt creator创建一个python文件,命名为script.py。也可以通过其他文本编辑器来创建。script.py中的内容如下:

# This Python file uses the following encoding: utf-8

# if__name__ == "__main__":
#     pass

def hello(arg1, arg2):
    return "hello python" + "; arg1=" + arg1 + "; arg2 = "  + arg2

3.2. 调用python脚本

步骤:

  • 调用Py_Initialize()进行初始化;
  • 调用Py_IsInitialized()判断初始化是否成功;
  • 将脚本文件所在目录追加到python的sys模块的path中;
  • 导入模块并获取需要调用的函数,模块名称就是脚本文件的名称;
  • 设置参数;
  • 执行函数;
  • 处理返回值。

调用代码示例如下:

Py_Initialize();

    if (!Py_IsInitialized())
    {
        std::cout << "false" << std::endl;
        return -1;
    }

    PyRun_SimpleString("import sys");

    PyRun_SimpleString("sys.path.append('D:/work/code/cpython')"); 

    PyObject *module = PyImport_ImportModule("script");
    if (!module)
    {
        std::cout << "import module failed" << endl;
        return -1;
    }
    PyObject *func = PyObject_GetAttrString(module, "hello");
    if (!func)
    {
        std::cout << "get function failed" << endl;
        return -1;
    }

    // 设置参数
    PyObject *args =  Py_BuildValue("ss", "hello", "world");

    // 返回值
    PyObject *rets = PyObject_CallObject(func, args);
    const char * returnStr = PyUnicode_AsUTF8(rets);
    cout << returnStr << endl;

上例中,设置参数还以使用下面这种方式:

PyObject * args = PyTuple_New(2);  // 2表示参数的个数
    PyTuple_SetItem(args, 0, Py_BuildValue("s", "hello")); // 0 表示第一个参数
    PyTuple_SetItem(args, 1, Py_BuildValue("s", "world")); // 1 表示第二个参数

3.3. 关于引入python头文件

    在纯的c++程序中,引入python头文件直接使用#include <Python.h> 即可。而如果是在Qt程序中,则需要向下面这样引入:

#pragma push_macro("slots")
#undef slots
#include <Python.h>
#pragma pop_macro("slots")

这是因为在Python和Qt中都定义了slots,如果一个类继承自QObject,这时再引入<Python.h>时,两者之间就会有冲突。在编译时会出现如下的错误:

QT 用python写代码吗 qt可以用python吗_QT 用python写代码吗_03

4. 常见错误

  • 提示找不到python37_d.lib。这种错误是因为安装python时没有安装debug环境。参照第1步中步骤,重新安装python或者再次运行python安装包,选择“修改”,将python的debug环境安装上即可。
  • 在qt creator中以debug方式运行程序时,出现CDB崩溃。这种错误是因为程序运行时调用的python版本与程序中配置的python库版本不一致。可以查看下环境变量以及qt creator中配置的python版本。在qt creator中查看python版本的方式,点击“工具” ==》 “选项”。如下:

QT 用python写代码吗 qt可以用python吗_QT 用python写代码吗_04

重新安装或修改python环境后,需要重启qt creator。qt creator会自动识别出当前系统安装的pyhon环境。