2016-07-24 8 views
1

IPython/Jupyterノートブックに似たものを構築しようとしています。私はQT5で自分のアプリケーションを書いていますので、これはネイティブアプリケーションにPythonを組み込むことに関連しています。matplotlib.pyplotのインポート時にPythonがクラッシュする

私はPythonを埋め込む方法と、ユーザーが入力したスクリプトを実行する方法を理解しました。私はプロットライブラリ(matplotlibなど)を使用して、私のアプリケーションでその出力を表示したいと考えています。 (実際には、私がしようとしていることは、this questionに記載されているものと非常に似ているように見えます)。

import matplotlib.pyplotを使用してプロットライブラリをインポートしようとすると、私のアプリケーションsegfaults(私はデバッグしようとしましたが、クラッシュは自分のコードにないので、何も分かりません)。

埋め込みPythonの初期化と任意のスクリプトの実行に使用するコードは、この質問の最後に表示されています。

他のライブラリ(例:sysまたはnumpy)を読み込むことができます。輸入できるのはmatplotlibです。しかし、matplotlib.pyplotをインポートしようとすると、segfaultsになります。

誰にも提案はありますか?

編集: QTを使用して原因が(何らかの理由で)原因と判断されました。私はmatplotlibのをインポートし、単純なCまたはC++プログラムをコンパイルすると、それはありませんないセグメンテーション違反...

私のコード:このクラッシュの理由はQTのバージョン間の競合であることが判明し

#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; 
} 
+0

なぜPythonを埋め込むのですか? – user4759923

+0

私はIPythonのノートブックに似たものを作ることができるかどうかを見たいと思っています。 – tcpie

+0

これは意味をなさない(Qtは非常に良い) – user4759923

答えて

2

まず、次の最小限のコードを使用して問題を再現できます。 main.hの "Q_OBJECT"行をコメントアウトすると、すべての場合のクラッシュを防ぐことができます。

ファイルmain.h:

#ifndef MAIN_H 
#define MAIN_H 

#include <QMainWindow> 

class test : public QMainWindow 
{ 
    Q_OBJECT // Commenting out this line prevents the crash 
}; 

#endif // MAIN_H 

ファイルmain.cppに:

#include <Python.h> 
#include "main.h" 

int main() 
{ 
    Py_Initialize(); 
    PyRun_SimpleString("import matplotlib.pyplot as plt");  
    PyRun_SimpleString("print('If we are here, we did not crash')"); 

    Py_Finalize(); 
    return 0; 
} 

私はアナコンダ経由のpython3を実行しています。しかし、QT5を私のパッケージマネージャー(私の場合はapt-get on Ubuntu)にインストールしました。私は問題は、私のパッケージマネージャーからインストールしたバージョンとは異なるQT5バージョンを使用している私のAnacondaインストールのmatplotlibにあると考えています。

修正が簡単です:私のpackage-managerでmatplotlibをインストールすると問題が解決します! (私のUbuntuシステム上:sudo apt-get install python3-matplotlib

関連する問題