天天看點

Qt調用Python詳細過程

作者:QT進階進階

1、建立Qt工程

Qt調用Python詳細過程

2、添加Python檔案

Qt調用Python詳細過程

編寫Python代碼,項目結構如下圖示:

Qt調用Python詳細過程

3 、添加Python庫

在工程檔案中加上Python安裝路徑下的​include​​​和​​libs​​路徑:

Qt調用Python詳細過程
INCLUDEPATH += C:\Users\Administrator\AppData\Local\Programs\Python\Python37\include
LIBS += -LC:\Users\Administrator\AppData\Local\Programs\Python\Python37\libs -lpython37
//注意:-L 和 PATH 之間不能有空格           

注意:此處必須根據自己的安裝情況做修改

Qt調用Python詳細過程

4、調用Python子產品

#ifndef
#define

#include <QMainWindow>
#include <Python.h>
#include <iostream>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};
#endif// MAINWINDOW_H           
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //Python初始化
    Py_Initialize();
    if( !Py_IsInitialized() )
        qDebug()<<"初始化失敗";

    //導入sys子產品設定子產品位址
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");
    //QString setSysPath = QString("sys.path.append('%1')").arg(QCoreApplication::applicationDirPath());
    //PyRun_SimpleString(setSysPath.toStdString().c_str());

    //建立子產品指針
    PyObject* pModule = PyImport_ImportModule("Py_Module");
    if (!pModule)
        qDebug()<<"擷取子產品指針失敗";

    //建立函數指針
    PyObject* pFunc= PyObject_GetAttrString(pModule,"add");
    if(!pFunc)
        qDebug()<<"擷取函數指針失敗";

    //建立函數參數,方法1
    PyObject* pPara = PyTuple_New(2);        // 2個參數
    PyTuple_SetItem(pPara, 0, Py_BuildValue("i",1));  //參數1為int型 1
    PyTuple_SetItem(pPara, 1, Py_BuildValue("i",2));  //參數2為int型 2
    //pPara = Py_BuildValue("(i,i)",1,2); //連寫方式

    /*
    PyObject* pPara = PyTuple_New(2);        // 2個參數
    PyTuple_SetItem(pPara, 0, Py_BuildValue("s","Hello"));  //參數1為String型 "Hello"
    PyTuple_SetItem(pPara, 1, Py_BuildValue("s","World!"));  //參數2為String型 "World!"
    */
    
    /// s 将C字元串轉換成Python對象,如果C字元串為空,傳回NONE
    /// c 将C類型的char轉換成長度為1的Python字元串對象
    /// i 将一個C類型的int轉換成Python int對象
    /// l 将C類型的long轉換成Pyhon中的int對象
    /// f 将C類型的float轉換成python中的浮點型對象
    /// d 将C類型的double轉換成python中的浮點型對象

    //建立函數參數,方法2
    PyObject* args = PyTuple_New(2);        // 2個參數
    PyObject* arg1 = PyLong_FromLong(4);    // 參數一設為4
    PyObject* arg2 = PyLong_FromLong(3);    // 參數二設為3
    PyTuple_SetItem(args, 0, arg1);
    PyTuple_SetItem(args, 1, arg2);

    //調用Python函數,傳入元組參數pPara
    PyObject *FuncBack = PyObject_CallObject(pFunc,pPara);
    //PyObject_CallObject(pFunc,nullptr); //無參數調用

    //FuncBack是傳回值指針,轉換擷取傳回值
    int res = 0;
    PyArg_Parse(FuncBack,"i",&res);
    qDebug()<<"傳回值: "<<res;

    //調用結束,銷毀
    Py_Finalize();

}

MainWindow::~MainWindow()
{
    delete ui;
}           

5、移動檔案

編寫完上述代碼之後,直接運作,會得到:

QT開發交流君羊:714620761
擷取子產品指針失敗           

要保證Qt可執行檔案與Python源檔案在同一級目錄下,方可正常運作

是以将工程下的​​Py_Module.py​​​複制到建構目錄下的​​debug​​檔案夾中:

Qt調用Python詳細過程

6、運作結果

Qt調用Python詳細過程

7、錯誤總結及解決辦法

錯誤1:找不到​​Python.h​​

出現原因: 因為我們在c++中使用這個了頭檔案,是以出現了找不到python.h
解決辦法: 在.pro檔案中添加python的頭檔案以及靜态連結庫,參考:3 、添加Python庫           

錯誤2:

PyType_Slot *slots; object.h(445) : error C2059: 文法錯誤:“;”
object.h(445) : error C2238: 意外的标記位于“;”之前           

解決辦法:把slots改成slots1,Python将slots作為變量,而Qt将slots作為關鍵字,是以沖突了,再次編譯該問題就沒有了

錯誤3:

Qt調用Python詳細過程

解決辦法:簡單粗暴,直接注釋掉