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

时间:2013-09-07 23:40:12

标签: python qt matplotlib pyqt python-embedding

我正在开发一个Qt / C ++中面向数学的GUI应用程序,并希望嵌入一个Python脚本,包括NumPy和Matplotlib。使用Python C API,我终于设法运行一个脚本,从Python变量中检索值,包括NumPy数组等。但是我将Matplotlib图表绘制到我的Qt / C ++应用程序中失败了。

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

但是我仍然缺少它的交互行为,调整大小等等虽然它似乎可以通过将Qt鼠标事件转发到figure.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。但是,当我尝试使用Python的C API在C ++代码中模仿它时,我只是用PyObject *画布结束,不知道如何将它转换为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)

正如我写的那样,我必须遗漏一些明显的东西。我用谷歌搜索,但没有成功。任何帮助都将非常感激。

1 个答案:

答案 0 :(得分:2)

对于PySide,我建议阅读this comp.lib.qt.pyside thread以及PySide文档中type converters的部分。我不能保证this code的绝对正确性,但它似乎做你想要的。

对于PyQt,the same comp.lib.qt.pyside thread链接到unwrapping SIP objects的示例,这正是您所需要的。