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

11

我正在使用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 * 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)

就像我写的那样,我一定漏掉了某些显而易见的东西。我已经在Google上搜索了很多次,但都没有成功。非常感谢任何帮助。


这是一个有趣的问题,您想在C++中包装一个C++类的Python包装器 ;) 您是正确的,FigureCanvasQTAgg确实是一个QWidget对象,但我对嵌入不了解足够多,无法获取底层QT对象的引用。 - tacaswell
tcaswell - 是的,这正是我所需要的 - 从PyObject中提取参考、指针或任何QWidget。 - HiFile.app - best file manager
我的唯一建议是深入了解PyQtPySide的底层实现。 - tacaswell
这个回答解决了你的问题吗? - tacaswell
非常抱歉没有及时回复,感谢您的耐心等待。我会检查建议的解决方案。然而,我决定采用更安全的方式,将整个应用程序重新制作为纯Python+PyQt应用程序,与Qt/C++相比可能存在一些性能缺陷,但目前看来仍然令人满意。无论如何,出于好奇心,我会测试一下您和bks提出的建议。感谢您的帮助。 - HiFile.app - best file manager
我认为这个问题应该得到更多的关注,因为越来越多的开发人员(包括我自己)发现将 Matplotlib 与 C++ 应用程序接口连接是一种比 qwt 或其他具有平均以下渲染能力和有限绘图 API 的库更好的绘图解决方案。对于感兴趣的人,请查看这个 Github 项目 - SAAD
1个回答

1

4
你能否概括一下链接的内容?它们看起来没问题,但链接会失效,这会降低答案的长期有用性。 - tacaswell
1
这不是一个有意义的回应,更不是一个答案。 - Lenz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接