Ich bin am irren, versuchen, etwas ähnliches IPython/Jupyter Notebooks zu bauen. Ich schreibe meine Anwendung in QT5, so viel davon hängt mit dem "Einbetten" von Python in einer nativen Anwendung zusammen.Embedded Python stürzt beim Import von Matplotlib.pyplot
Ich habe herausgefunden, wie man Python einbetten kann und wie man Skripte ausführen kann, die vom Benutzer eingegeben werden. Ich möchte in der Lage sein, Plotbibliotheken (wie Matplotlib) zu verwenden und ihre Ausgabe in meiner Anwendung anzuzeigen. (Tatsächlich scheint das, was ich zu tun versuche, sehr ähnlich dem zu sein, was in this question beschrieben ist).
Wenn ich jedoch versuche, die Plot-Bibliothek mit import matplotlib.pyplot
zu importieren, meine Anwendung segfaults (Ich habe versucht zu debuggen, aber der Absturz ist nicht in meinem Code, so kann ich nichts vernünftiges daraus bekommen).
Der Code, den ich verwende, um das eingebettete Python zu initialisieren und willkürliche Skripts auszuführen, wird am Ende dieser Frage angezeigt.
Ich kann andere Bibliotheken (wie sys
oder numpy
) in Ordnung importieren. Ich kann matplotlib
in Ordnung importieren. Aber wenn ich versuche, matplotlib.pyplot
zu importieren, segfaults.
Hat jemand irgendwelche Vorschläge?
EDIT: Ich habe festgestellt, dass die Ursache (aus irgendeinem Grund) bei mir mit QT liegt. Wenn ich eine einfache C oder C++ Programm kompilieren, die matplotlib importiert, hat es nicht segfault ...
Mein Code:
#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;
}
Warum versuchen Sie, Python einzubetten? – user4759923
Ich möchte sehen, ob ich etwas ähnliches zu IPython-Notebooks machen kann, aber in einer nativen Anwendung. – tcpie
Ich bezweifle, dass das Sinn macht (Qt ist sehr gut) – user4759923