I need to call python from qt c++ (qmake) and share data between them. So I wrote this code but the error is logical, I mean no error but it stops unexpectedly.
I tried this with python2.7 too but the same error. I want to pass a to someFunction function and return it back to the main.cpp
code:
someFunction.py: (I put this in "Otherfile" section of the project)
def someFunction(a):
return a
main.cpp:
#include <Python.h>
#undef B0
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
PyObject* myModuleString = PyUnicode_FromString((char*)"arbName");
PyObject* myModule = PyImport_Import(myModuleString);
PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"someFunction");
PyObject* args = Py_BuildValue("(d)", 2.0);
PyObject *myResult = PyObject_CallObject(myFunction, args);
qDebug() << "Hello World";
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
qmake:
QT += core gui
INCLUDEPATH = /usr/include/python3.8
LIBS += -lpython3.8
CLANG_INSTALL_DIR += usr/lib/clang/10/lib/linux
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
CONFIG += no_keywords
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
someFunction.py
You have 2 problems:
You use someFunction
but the module is called arbName
.
The "." It indicates the directory where the application is executed, in the case that you use QtCreator it is the build directory and not the source code folder. On the other hand it is better to avoid using relative paths but rather to construct absolute paths. For this you must use QCoreApplication::applicationDirPath()
. In addition to copying the file and to do it automatically then you can use this answer.
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
CONFIG += no_keywords
INCLUDEPATH = /usr/include/python3.8
LIBS += -lpython3.8
CONFIG += file_copies
COPIES += python
python.files = someFunction.py
python.path = $$OUT_PWD
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
DISTFILES += \
someFunction.py
main.cpp
#include "mainwindow.h"
#include <Python.h>
#include <QDebug>
#include <QApplication>
int main(int argc, char *argv[])
{
Py_Initialize();
QString sys_path_append_command = QString(R"(sys.path.append("%1"))").arg(QCoreApplication::applicationDirPath());
PyRun_SimpleString("import sys");
PyRun_SimpleString(sys_path_append_command.toStdString().c_str());
PyObject* myModuleString = PyUnicode_FromString((char*)"someFunction");
PyObject* myModule = PyImport_Import(myModuleString);
PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"someFunction");
PyObject* args = Py_BuildValue("(f)", 2.0);
PyObject *myResult = PyObject_CallObject(myFunction, args);
qDebug() << "Hello World" << PyFloat_AsDouble(myResult);
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}