一、環境配置
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