python - 在 QT 应用程序中嵌入 Python3.5 脚本
问题描述
我正在尝试将包含一个类的 python 脚本 (python 3.5) 嵌入到我的 QT c++ 应用程序中。在尝试 GUI 之前,我尝试了一个简单的控制台应用程序。问题是当我选择“QT 控制台应用程序”作为新项目类型时,代码会崩溃,但如果我选择“普通 C++ 应用程序”(非 QT 项目选项),程序会按预期工作!
Python脚本:
import numpy as np
import dlib
# some other imports that also imports other modules
class myclass:
def __init__(self, path1, path2, path3, use_Test=True):
self.p1 = path1
self.p2 = path2
self.p3 = path3
self.test = use_Test
# some other functions
def add(self, x, y):
return x+y
这是我在普通 C++ 应用程序中尝试的代码:
首先在 .pro 文件中:
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
INCLUDEPATH += /usr/include/python3.5
LIBS += -L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu -lpython3.5
C++ 代码:
#include <iostream>
#include <Python.h>
using namespace std;
int main()
{
setenv("PYTHONPATH", ".", 1);
Py_Initialize();
PyObject* module = PyImport_ImportModule("myscript");
assert(module != NULL);
PyObject* dict = PyModule_GetDict(module);
assert(module != NULL);
Py_DECREF(module);
PyObject* python_class = PyDict_GetItemString(dict, "myclass");
assert(python_class != NULL);
Py_DECREF(dict);
PyObject* engine;
if (PyCallable_Check(python_class))
{
PyObject *args = Py_BuildValue("(sss)", "s1", "s2", "s3");
PyObject *keywords = PyDict_New();
PyDict_SetItemString(keywords, "tester", Py_False);
engine = PyObject_Call(python_class, args, keywords);
Py_DECREF(python_class);
Py_DECREF(args);
Py_DECREF(keywords);
}
else
{
std::cout << "Cannot instantiate the Python class" << std::endl;
Py_DECREF(python_class);
return 1;
}
PyObject *value = PyObject_CallMethod(engine, "add", "(ii)", 2, 4);
int result = PyLong_AsLong(value);
cout<<"Result = "<<result<<endl;
cout << "Hello World!" << endl;
Py_Finalize();
return 0;
}
此代码正常工作,我从 add 函数中获得了所需的结果。但是转到QT控制台App,代码变为:
亲:
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
CONFIG += no_keywords #Solve Python SLOT ISSUE
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp
INCLUDEPATH += /usr/include/python3.5
#INCLUDEPATH += /usr/local/lib/python3.5/dist-packages/numpy/core/include/numpy
LIBS += -L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu -lpython3.5
C++
#include <QCoreApplication>
#include <Python.h>
#include <QDir>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
setenv("PYTHONPATH", ".", 1);
Py_Initialize();
PyObject* module = PyImport_ImportModule("myscript");
assert(module != NULL);
PyObject* dict = PyModule_GetDict(module);
assert(module != NULL);
Py_DECREF(module);
PyObject* python_class = PyDict_GetItemString(dict, "myclass");
assert(python_class != NULL);
Py_DECREF(dict);
PyObject* engine;
if (PyCallable_Check(python_class))
{
PyObject *args = Py_BuildValue("(sss)", "s1", "s2", "s3");
PyObject *keywords = PyDict_New();
PyDict_SetItemString(keywords, "tester", Py_False);
engine = PyObject_Call(python_class, args, keywords);
Py_DECREF(python_class);
Py_DECREF(args);
Py_DECREF(keywords);
}
else
{
std::cout << "Cannot instantiate the Python class" << std::endl;
Py_DECREF(python_class);
return 1;
}
PyObject *value = PyObject_CallMethod(engine, "add", "(ii)", 2, 4);
int result = PyLong_AsLong(value);
cout<<"Result = "<<result<<endl;
cout << "Hello World!" << endl;
Py_Finalize();
return a.exec();
}
但是每当我尝试运行代码时,它就会崩溃(崩溃发生在 PyObject* module = PyImport_ImportModule("myscript"); 行)
我搜索了一个解决方案,并建议在 Py_Initialize(); 之后添加以下内容。
QString qs = QDir::currentPath();
std::wstring ws = qs.toStdWString();
PySys_SetPath(ws.data());
这有助于不使代码崩溃,但现在我所有的 python 导入都是错误(即:ImportError: No module named 'numpy')
我在 QT APP 中缺少什么?QT和Python之间有冲突吗?
解决方案
推荐阅读
- vb.net - Visual Basic:TRY\CATCH 异常处理问题
- javascript - 具有不同 [(ngModel)] 输入的 Angular 6 重用表单
- java - 在 Android 应用游戏上玩游戏时使用背景音乐
- mysql - mysql 在连接尝试时自动启动
- c# - 捕获数字电视并将其流式传输到本地网络
- ruby - 如何在vim中删除ruby周围的块(do / end)
- javascript - 单击模式时如何在另一个选项卡中打开 URL
- node.js - 无法将 MongoDB 与 nodejs 连接
- java - 使用 nextLine() 在 Java 中获取名称的长度
- jquery - jsTree 默认箭头/三角形图标配置