玉器哪家網站做的好個人網站備案
一.概述
1.Python功能強大,很多Qt或者c/c++開發(fā)不方便的功能可以由Python編碼開發(fā),尤其是一些算法庫的應用上,然后Qt調用Python。
2.在Qt調用Python的過程中,必須要安裝python環(huán)境,并且Qt Creator中編譯器與Python的版本要對應,具體來說編譯器是64位安裝Python就是64位,編譯器32位安裝Python就是32位。
3.本文測試使用的QT版本為:QT5.12; ?python版本為python-3.12
4.Qt調用python主要有兩種方式:
一是混合編程模式,直接調用python文件內的函數,比較靈活,也是本文重點講述的方法;
二是直接調用python腳本文件,比較簡單,但是不夠靈活。
二.混合編程代碼實現(xiàn)
1.環(huán)境配置
(1)pro文件中添加python的頭文件和依賴庫:
INCLUDEPATH += -I D:\python\Lib\site-packages\numpy\core\include
INCLUDEPATH += -I D:\python\include
LIBS += -L D:\python\libs -l_tkinter -lpython3 -lpython312
(2)修改include文件夾中的object.h文件,因為Python中slots是關鍵字,Qt中slots也是關鍵字,會沖突。
#undef slots
????PyType_Slot *slots; /* terminated by slot==0. */
#define slots Q_SLOTS ?
2.代碼實現(xiàn)
(1)Python代碼添加目錄及內容
添加test1.py文件到qt生成exe目錄,比如:
../build-qt_python-Desktop_Qt_5_12_10_MinGW_64_bit-Debug/debug/testb.py
否則無法調用py文件。
Python代碼:
def hello():
????print("hello")
def mix(a,b):
????print("=======================")
????r1 = a + b
????r2 = a - b
return (r1, r2)
2.qt代碼
#include <QCoreApplication>
#include <Python.h>
#include <QDebug>
#include <numpy/arrayobject.h>
int Test_hello(void)
{
????//初始化python模塊
????Py_Initialize();
????if ( !Py_IsInitialized() )
????{
????????return -1;
????}
????//導入testb.py模塊
????PyObject* pModule = PyImport_ImportModule("testb");
????if (!pModule) {
????????qDebug("Cant open python file!\n");
????????return -1;
????}
????//獲取test模塊中的hello函數
????PyObject* pFunhello= PyObject_GetAttrString(pModule,"hello");
????if(!pFunhello){
????????qDebug()<<"Get function hello failed";
????????return -1;
????}
????//調用hello函數
????PyObject_CallFunction(pFunhello,NULL);
????//結束,釋放python
????Py_Finalize();
????return 0;
}
int Testt_mix(void)
{
????//初始化python模塊
????Py_Initialize();
????if ( !Py_IsInitialized() )
????{
????????return -1;
????}
????PyObject* pModule = PyImport_ImportModule("testb");//注意文件名字大小寫
????if (!pModule) {
????????qDebug("Cant open python file!\n");
????????return -1;
????}
????PyObject* pyFunc_mix = PyObject_GetAttrString(pModule, "mix");
????if (pModule && PyCallable_Check(pyFunc_mix))
????{
????????PyObject* pyParams = PyTuple_New(2); //定義兩個變量
????????PyTuple_SetItem(pyParams, 0, Py_BuildValue("i", 5));// 變量格式轉換成python格式
????????PyTuple_SetItem(pyParams, 1, Py_BuildValue("i", 2));// 變量格式轉換成python格式
????????int r1 = 0, r2 = 0;
????????PyObject* pyValue = PyObject_CallObject(pyFunc_mix, pyParams); //調用函數返回結果
????????PyArg_ParseTuple(pyValue, "i|i", &r1, &r2);//分析返回的元組值
????????if (pyValue)
????????{
????????????qDebug("result: %d ??%d\n", r1, r2);
????????}
????}
????//結束,釋放python
????Py_Finalize();
????return 0;
}
int main(int argc, char *argv[])
{
????QCoreApplication a(argc, argv);
????Test_hello();
????Testt_mix();
???return a.exec();
}
3.輸出結果
三.直接調用python腳本模式
1.python文件
import sys
def test():
????a = 1
????print (a)
if __name__=='__main__':
???b = test()
???print (b)
2.QT代碼
??????//第一步:初始化Python
??????Py_Initialize();
??????//檢查初始化是否完成
??????if (!Py_IsInitialized())
??????{
??????????return -1;
??????}
??????//第二步:導入sys模塊
??????PyRun_SimpleString("import sys");
??????const char* code = "with open('./debug/scriptpy.py', 'r') as file: exec(file.read())";
??????// 執(zhí)行代碼字符串
??????if (PyRun_SimpleString(code) != 0)
??????{
??????????// 處理錯誤
??????????PyErr_Print();
??????????return -1;
??????}
??????Py_Finalize();
3.執(zhí)行結果