1、 Win 64環境下載及安裝 Miniconda
首先下載Windows?版Miniconda,https://docs.conda.io/en/latest/miniconda.html或
https://repo.anaconda.com/miniconda/
安裝界面及選擇如下圖所示:
安裝完python3.12版報錯如下。
說明:python3.11版本以后都不支持Py_SetPythonHome函數為此,下載了python3.10版本。
版本問題是程序員的硬傷!!!
2、創建虛擬環境
新建Qt工程pythondemo,在pro文件中添加程序生成目錄 DESTDIR及添加頭文件和庫文件內容如下:
QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = PythonDemo
TEMPLATE = app
DESTDIR = $$PWD/bin #Added By LZY# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0CONFIG += c++11SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.uiINCLUDEPATH += $$PWD/bin/python/env/include #Added By LZY
LIBS += -L$$PWD/bin/python/env/libs \-lpython310 -lpython3# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
編譯并運行程序,可以看到在bin目錄下生成了可執行程序。在bin目錄下新建python目錄,然后在開始菜單中找到 **Anaconda Prompt(miniconda3)**打開一個Python終端,默認激活的是base虛擬環境。使用如下命令創建指定路徑,指定Python版本的虛擬環境:
#1)指定Python版本的虛擬環境:并按照提示選擇Y
conda create --prefix D:\LZY\SelfSearch\Src\PythonDemo\bin\python\env python=3.10
#2)激活虛擬環境:
conda activate D:\LZY\SelfSearch\Src\PythonDemo\bin\python\env
3、 配置C++調用python環境
初始化 Python 環境,并在程序中設置 PythonHome 環境變量,如何知道PythonHome環境變量需要設置哪些路徑呢?這里需要參考虛擬環境的環境變量值。在激活的 bin\python\env 虛擬環境下運行Python解釋器,打印虛擬環境的path值,如下所示:
(D:\LZY\SelfSearch\Src\PythonDemo\bin\python\env) D:\LZY\SelfSearch\Src\PythonDemo>python
Python 3.10.16 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 16:19:12) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.path)
['', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\python310.zip', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\DLLs', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\lib', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\lib\\site-packages']
>>>
在代碼中設置PythonHome 并初始化Python環境,代碼如下:
QString pythonHome = qApp->applicationDirPath() + "/python/env";pythonHome.append(";");pythonHome.append(qApp->applicationDirPath() + "/python/env/python38.zip");pythonHome.append(";");pythonHome.append(qApp->applicationDirPath() + "/python/env/DLLs");pythonHome.append(";");pythonHome.append(qApp->applicationDirPath() + "/python/env/lib");pythonHome.append(";");pythonHome.append(qApp->applicationDirPath() + "/python/env/lib/site-packages");wchar_t pythonHomeWchar[1500];memset(pythonHomeWchar, 0, sizeof(pythonHomeWchar));pythonHome.toWCharArray(pythonHomeWchar);//設置PythonHome環境變量Py_SetPythonHome(pythonHomeWchar);//初始化Python C APIPy_Initialize();if(Py_IsInitialized()){qDebug() << "python env init !";}
編譯問題:
在配置好pro文件編譯qt工程時遇到如下圖所示的錯誤,原因是object中定義的slots與qt的slots定義沖突,解決方法是在頭文件python.h聲明前先取消slots宏定義,包含python.h后再重新define,可解決這個問題。如下圖所示:
#include <QDebug>
#include <qtextcodec.h>#include "mainwindow.h"
#include "ui_mainwindow.h"
//--
#undef slots //Added By Lzy
#include "Python.h"
#define slots Q_SLOTS
4、 C++調用Python帶參函數
創建testPython.py文件,并添加一個帶參數的測試函數,如下
def writeData(data):print(data)
下面的代碼演示了如何設置應用程序python腳本路徑,導入Python模塊,獲取模塊中定義的函數,設置函數參數及調用函數。
//應用程序python腳本路徑QString pyfilePath = QString::fromLocal8Bit("sys.path.append('%1')").arg(qApp->applicationDirPath() + "/python");PyRun_SimpleString(pyfilePath.toLocal8Bit().data());//導入python模塊PyObject* pWriteWordModule = PyImport_ImportModule("testPython");if(!pWriteWordModule){qDebug() << "import module faild!";PyErr_Print();}//獲取testPython模塊中的函數PyObject *pFunc = PyObject_GetAttrString(pWriteWordModule, "writeData");if(!pFunc){qDebug() << "get func faild!";}//設置函數參數PyObject *pTuple = PyTuple_New(1);PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "hello python !"));//調用函數PyObject_CallObject(pFunc, pTuple);
5、問題處理
1)調用python模塊出錯如下:
Traceback (most recent call last):File "D:\LZY/SelfSearch/Src/PythonDemo/bin/python\testPython.py", line 2, in writeDataprint(data)
UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd' in position 0: illegal multibyte sequence
解決方法:在頭文件中加入#pragma execution_character_set("utf-8")就可以;