将Matplotlib图表嵌入到Qt/C ++应用程序中 [英] Embedding a matplotlib chart into Qt/C++ application

查看:750
本文介绍了将Matplotlib图表嵌入到Qt/C ++应用程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am developing an math-oriented GUI application in Qt/C++ and would like to embed a Python scripting, including NumPy and Matplotlib. Using Python C API, I finally managed to run a script, retrieve the values from the Python variables, including NumPy arrays etc. But I failed at drawing Matplotlib charts into my Qt/C++ application.

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

It is better to say, I have managed to save the chart's RGBA buffer to a variable using Python script, then get the value of the variable as a PyObject of buffer type, get the buffer and transform it to QImage then to QPixmap and finally put it into QLabel and display it.

但是我仍然缺少它的交互行为,调整大小等.尽管似乎可以通过将Qt鼠标事件转发到fig.canvas.button_press_event来完成,但随后变得过于复杂...所以我得出结论,我不充分了解Python嵌入的原理.我缺少明显的东西.

But I am still missing its interactive behaviour, resizing etc. though it seems that it can be done by forwarding Qt mouse events to figure.canvas.button_press_event but it is then getting overly complicated... So I concluded I do not understand the principles of Python embedding well enough. I am missing something obvious.

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

I found some samples of embedding matplotlib charts into PyQt or PySide (i.e. written in Python) applications where I have seen something like QMainWindow.setCentralWidget(canvas) or layout.addWidget(canvas). Here canvas is FigureCanvasQTAgg object ( http://matplotlib.org/api/backend_qt4agg_api.html ).

这表明canvas继承自QWidget.但是,当我尝试使用Python的C API在C ++代码中模拟这一点时,我仅以PyObject * canvas结尾,不知道如何将其转换为QWidget.这是我的片段,没有重要步骤:

This suggests that canvas inherits from QWidget. But when I try mimic this in C++ code using Python's C API, I end with just a PyObject *canvas, not knowing how to trasform it to a QWidget. This is my snippet without the important step:

//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,但没有成功.任何帮助将不胜感激.

As I wrote, I must be missing something obvious. I googled everywhere but without success. Any help would be very appreciated.

推荐答案

对于PySide,我建议阅读此comp.lib.qt.pyside线程,以及此代码的绝对正确性,但是似乎可以满足您的要求.

For PySide, I suggest reading this comp.lib.qt.pyside thread and also the section on type converters in the PySide docs. I can't vouch for the absolute correctness of this code, but it appears to do what you want.

对于PyQt,相同的comp.lib.qt.pyside线程链接到展开SIP对象的示例您需要什么.

For PyQt, the same comp.lib.qt.pyside thread links to an example of unwrapping SIP objects which is again exactly what you need.

这篇关于将Matplotlib图表嵌入到Qt/C ++应用程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆