将matplotlib图表嵌入Qt/C++应用程序中

11 人关注

我正在用Qt/C++开发一个面向数学的GUI应用程序,想嵌入一个Python脚本,包括NumPy和Matplotlib。使用Python C API,我终于成功地运行了一个脚本,从Python变量中获取了数值,包括NumPy数组等。但我在Qt/C++应用程序中绘制Matplotlib图表时失败了。

最好是说,我已经设法用Python脚本将图表的RGBA缓冲区保存为一个变量,然后将变量的值作为缓冲区类型的PyObject来获取,获取缓冲区并将其转换为QImage然后转换为QPixmap,最后将其放入QLabel并显示。

但我仍然缺少它的交互行为,如调整大小等。虽然似乎可以通过将Qt鼠标事件转发到fig.canvas.button_press_event来实现,但这样做会变得过于复杂。所以我得出结论,我对Python嵌入的原理理解得还不够透彻。我错过了一些明显的东西。

我发现了一些将matplotlib图表嵌入PyQt或PySide(即用Python写的)应用程序的例子,我看到了类似QMainWindow.setCentralWidget(canvas)或layout.addWidget(canvas)。这里的canvas是FigureCanvasQTAgg对象( http://matplotlib.org/api/backend_qt4agg_api.html ).

这表明canvas继承于QWidget。但是当我试图在 C++ 代码中使用 Python 的 C API 来模仿这一点时,我最终只得到了一个 PyObject *canvas,不知道如何将其转化为 QWidget。这是我的片段,没有重要的步骤。

//draw a figure in Python script called from C++ app
PyRun_SimpleString("import matplotlib\n"
"matplotlib.use('Qt4agg')\n" //use Qt4 backend
"import pylab\n"
"pylab.plot(randn(10))\n" //plot something
"fig = pylab.gcf()\n" //take current figure
"canvas = fig.canvas" //canvas is of FigureCanvasQTAgg type
//get canvas as PyObject
PyObject* m = PyImport_AddModule("__main__");
PyObject* canvas = PyObject_GetAttrString(m, "canvas");
//from what I know, canvas is a PyObject wrapped around an object derived from QWidget
//...
//... here I do not know how to convert canvas (i.e. PyObject) into canvasWidget (i.e. QWidget)???
//... 
//show chart as a widget
MyWindow.setCentralWidget(canvasWidget)