玉器哪家網(wǎng)站做的好個(gè)人網(wǎng)站備案
一.概述
1.Python功能強(qiáng)大,很多Qt或者c/c++開(kāi)發(fā)不方便的功能可以由Python編碼開(kāi)發(fā),尤其是一些算法庫(kù)的應(yīng)用上,然后Qt調(diào)用Python。
2.在Qt調(diào)用Python的過(guò)程中,必須要安裝python環(huán)境,并且Qt Creator中編譯器與Python的版本要對(duì)應(yīng),具體來(lái)說(shuō)編譯器是64位安裝Python就是64位,編譯器32位安裝Python就是32位。
3.本文測(cè)試使用的QT版本為:QT5.12; ?python版本為python-3.12
4.Qt調(diào)用python主要有兩種方式:
一是混合編程模式,直接調(diào)用python文件內(nèi)的函數(shù),比較靈活,也是本文重點(diǎn)講述的方法;
二是直接調(diào)用python腳本文件,比較簡(jiǎn)單,但是不夠靈活。
二.混合編程代碼實(shí)現(xiàn)
1.環(huán)境配置
(1)pro文件中添加python的頭文件和依賴(lài)庫(kù):
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文件,因?yàn)镻ython中slots是關(guān)鍵字,Qt中slots也是關(guān)鍵字,會(huì)沖突。
#undef slots
????PyType_Slot *slots; /* terminated by slot==0. */
#define slots Q_SLOTS ?
2.代碼實(shí)現(xiàn)
(1)Python代碼添加目錄及內(nèi)容
添加test1.py文件到qt生成exe目錄,比如:
../build-qt_python-Desktop_Qt_5_12_10_MinGW_64_bit-Debug/debug/testb.py
否則無(wú)法調(diào)用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;
????}
????//導(dǎo)入testb.py模塊
????PyObject* pModule = PyImport_ImportModule("testb");
????if (!pModule) {
????????qDebug("Cant open python file!\n");
????????return -1;
????}
????//獲取test模塊中的hello函數(shù)
????PyObject* pFunhello= PyObject_GetAttrString(pModule,"hello");
????if(!pFunhello){
????????qDebug()<<"Get function hello failed";
????????return -1;
????}
????//調(diào)用hello函數(shù)
????PyObject_CallFunction(pFunhello,NULL);
????//結(jié)束,釋放python
????Py_Finalize();
????return 0;
}
int Testt_mix(void)
{
????//初始化python模塊
????Py_Initialize();
????if ( !Py_IsInitialized() )
????{
????????return -1;
????}
????PyObject* pModule = PyImport_ImportModule("testb");//注意文件名字大小寫(xiě)
????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); //定義兩個(gè)變量
????????PyTuple_SetItem(pyParams, 0, Py_BuildValue("i", 5));// 變量格式轉(zhuǎn)換成python格式
????????PyTuple_SetItem(pyParams, 1, Py_BuildValue("i", 2));// 變量格式轉(zhuǎn)換成python格式
????????int r1 = 0, r2 = 0;
????????PyObject* pyValue = PyObject_CallObject(pyFunc_mix, pyParams); //調(diào)用函數(shù)返回結(jié)果
????????PyArg_ParseTuple(pyValue, "i|i", &r1, &r2);//分析返回的元組值
????????if (pyValue)
????????{
????????????qDebug("result: %d ??%d\n", r1, r2);
????????}
????}
????//結(jié)束,釋放python
????Py_Finalize();
????return 0;
}
int main(int argc, char *argv[])
{
????QCoreApplication a(argc, argv);
????Test_hello();
????Testt_mix();
???return a.exec();
}
3.輸出結(jié)果
三.直接調(diào)用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;
??????}
??????//第二步:導(dǎo)入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)
??????{
??????????// 處理錯(cuò)誤
??????????PyErr_Print();
??????????return -1;
??????}
??????Py_Finalize();
3.執(zhí)行結(jié)果