TX2(Ubuntu)下QT(c++) + python3.6 混合編程

一、環境配置

1 TX2 (Ubuntu18.04)

2 QT 5.9.5

3 python 3.6

二、工程創建

2.1 建一個widget工程,這裏不做過多描述,搭配一個按鍵,在按鍵按下之後調用python的函數。

2.2 添加py文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#test.py
def testpy():
    print("hello world this is python")

文件的內容就是打印一句話。

三、python的調用

3.1 .pro文件中添加依賴庫以及依賴頭文件路徑


INCLUDEPATH += -I /usr/include/python3.6/

LIBS += -L  /usr/lib/python3.6/config-3.6m-aarch64-linux-gnu -lpython3.6

3.2  SLOT關鍵字修改

由於QT中定義了slots作爲關鍵了,而python3中有使用slot作爲變量,所以在編譯時會有衝突。

需要修改python庫中的object.h文件,因爲該文件是系統文件,可以在終端中sudo gedit進行修改:

sudo gedit /usr/include/python3.6/object.h
//應該是在440-448行
typedef struct{     
      const char* name;      
      int basicsize;    
      int itemsize;     
      unsigned int flags;
      
           #undef slots     //這裏取消slots宏定義
      PyType_Slot *slots;  /* terminated by slot==0. */
      #define slots Q_SLOTS  //這裏恢復slots宏定義與QT中QObjectDefs.h中一致
  } PyType_Spec; 

3.3 槽函數完成

void Widget::on_pushButton_clicked()
{
    qDebug()<<"test py";

    Py_Initialize();
    PyObject *pModule = nullptr;
    PyObject *pLoadFunc = nullptr;


    if (!Py_IsInitialized()) {

        //printf("inititalize failed");
        qDebug() << "inititalize failed";
        return ;
    }
    else {
        qDebug() << "inititalize success";
    }

    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')"); //可執行文件路徑

    pModule = PyImport_ImportModule("test_py");// py file name
    if (!pModule) {
        PyErr_Print();
        qDebug() << "not loaded!";
        return ;
    }
    else
    {
        qDebug() << "load module success";
    }


    pLoadFunc = PyObject_GetAttrString(pModule, "testpy"); // function name
    if (!pLoadFunc)
    {
        PyErr_Print();
        qDebug() << "not loaded pLoadFunc!";
        return ;
    }
    else {
        qDebug() << "load pLoadFunc success";
    }

    PyObject_CallFunction(pLoadFunc,NULL);
    Py_Finalize();
}

注意三個地方

1  可執行文件路徑  ./是指當前的可執行文件的路徑,確保路徑下有test_py.py

2  pModule = PyImport_ImportModule("test_py");  test_py是py文件名

3  pLoadFunc = PyObject_GetAttrString(pModule, "testpy"); testpy是函數名

尤其要注意1 很多人就會說,我的可執行程序路徑下並沒有test_py.py,test_py.py是在別的路徑下,怎麼辦?

那就把test_py.py copy到可執行程序目錄下

四、執行

五、帶參數傳遞

    pLoadFunc = PyObject_GetAttrString(pModule, "testpy"); // function name
    if (!pLoadFunc)
    {
        PyErr_Print();
        qDebug() << "not loaded pLoadFunc!";
        return ;
    }
    else
    {
        qDebug() << "load pLoadFunc success";
    }    

    PyObject* args = PyTuple_New(2);
    PyObject *pInt1=Py_BuildValue("i",20); //i means int
    PyObject *pInt2=Py_BuildValue("i",30);
    PyTuple_SetItem(args, 0, pInt1);
    PyTuple_SetItem(args, 1, pInt2);

    PyObject* pRet = PyObject_CallObject(pLoadFunc,args);
    int ans=0;
    PyArg_Parse(pRet,"i",&ans); //i means int
    qDebug()<<"ans = "<<ans;

 

def testpy(a,b):
    print("hello world this is python build")
    print(a)
    print(b)
    return a+b

 

參考:https://blog.csdn.net/lwlgzy/article/details/83857297

https://blog.csdn.net/m0_37706052/article/details/103457665

https://blog.csdn.net/qq_41800188/article/details/79709452

https://blog.csdn.net/u010168781/article/details/89927630  帶參數傳遞

https://www.cnblogs.com/jiaping/p/6321859.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章