【发布时间】:2016-07-24 01:13:13
【问题描述】:
我搞砸了,试图构建类似于 IPython/Jupyter 笔记本的东西。我正在使用 QT5 编写我的应用程序,其中大部分与在本机应用程序中“嵌入”Python 有关。
我想出了如何嵌入 python 以及如何允许它执行用户输入的脚本。我希望能够使用绘图库(例如 matplotlib),并在我的应用程序中显示它们的输出。 (事实上,我正在尝试做的事情似乎与this question 中描述的非常相似)。
但是,当我尝试使用 import matplotlib.pyplot 导入绘图库时,我的应用程序出现段错误(我尝试调试,但崩溃不在我的代码中,所以我无法从中得到任何明智的结果)。
我用来初始化嵌入式 Python 和运行任意脚本的代码显示在这个问题的底部。
我可以很好地导入其他库(例如sys 或numpy)。我可以导入matplotlib 很好。但是当我尝试导入matplotlib.pyplot 时,它会出现段错误。
有人有什么建议吗?
编辑: 我已经确定原因(出于某种原因)在于我使用 QT。当我编译一个导入 matplotlib 的简单 C 或 C++ 程序时,它确实 not segfault...
我的代码:
#include "pythoninteractor.h"
#include <QString>
#include <Python.h>
#include <string>
#include <QList>
PythonInteractor::PythonInteractor()
{
this->pyOutput_redir =
"import sys\n\
class CatchOutErr:\n\
def __init__(self):\n\
self.value = ''\n\
def write(self, txt):\n\
self.value += txt\n\
catchOutErr = CatchOutErr()\n\
sys.stdout = catchOutErr\n\
sys.stderr = catchOutErr\n\
"; //this is python code to redirect stdouts/stderr
QString paths[] = {"",
"/home/tcpie/anaconda3/lib/python35.zip",
"/home/tcpie/anaconda3/lib/python3.5",
"/home/tcpie/anaconda3/lib/python3.5/plat-linux",
"/home/tcpie/anaconda3/lib/python3.5/lib-dynload",
"/home/tcpie/anaconda3/lib/python3.5/site-packages",};
Py_SetProgramName(L"qt-notepad-tut");
Py_Initialize();
PyObject *pModule = PyImport_AddModule("__main__"); //create main module
PyRun_SimpleString(this->pyOutput_redir.toStdString().c_str()); //invoke code to redirect
PyObject *sys_path;
PyObject *path;
sys_path = PySys_GetObject("path");
if (sys_path == NULL)
return;
PySequence_DelSlice(sys_path, 0, PySequence_Length(sys_path));
for (size_t i = 0; i < sizeof(paths) / sizeof(QString); i++) {
path = PyUnicode_FromString(paths[i].toStdString().c_str());
if (path == NULL)
continue;
if (PyList_Append(sys_path, path) < 0)
continue;
}
}
QString PythonInteractor::run_script(QString script)
{
QString ret = "";
PyObject *pModule = PyImport_AddModule("__main__");
PyRun_SimpleString(script.toStdString().c_str());
PyErr_Print(); //make python print any errors
PyObject *catcher = PyObject_GetAttrString(pModule,"catchOutErr"); //get our catchOutErr created above
if (catcher == NULL) {
Py_Finalize();
return ret;
}
PyObject *output = PyObject_GetAttrString(catcher,"value"); //get the stdout and stderr from our catchOutErr object
if (output == NULL) {
return ret;
}
ret = QString(PyUnicode_AsUTF8(output));
return ret;
}
【问题讨论】:
-
为什么要尝试嵌入 Python?
-
我想看看我是否可以在原生应用程序中制作类似于 IPython 笔记本的东西。
-
我怀疑这是否有意义(Qt 非常好)
-
这是什么意思?
-
matplotlib.pyplot 可能不是一个好主意。如果我没记错的话,它会尝试创建自己的窗口。后端可能应该是
Agg、Cairo或Svg' (matplotlib.use('Svg')),即非图形化以生成 jpg、png 或 svg。
标签: python c++ qt matplotlib