Встраивание диаграммы matplotlib в приложение Qt / C++

Я разрабатываю математически ориентированное приложение GUI в Qt / C++ и хотел бы встроить скрипты Python, включая NumPy и Matplotlib. Используя Python C API, мне наконец удалось запустить скрипт, получить значения из переменных Python, включая массивы NumPy и т. д. Но мне не удалось нарисовать диаграммы Matplotlib в моем приложении Qt/C++.

лучше сказать, мне удалось сохранить буфер RGBA диаграммы в переменную с помощью скрипта Python, а затем получить значение переменная как PyObject типа буфера, получить буфер и преобразовать его в QImage затем QPixmap и, наконец, положить его в QLabel и отобразить его.

но мне все еще не хватает его интерактивного поведения, изменения размера и т. д. хотя кажется, что это можно сделать, перенаправив события мыши Qt на рисунок.холст.button_press_event, но это становится слишком сложным... Поэтому я пришел к выводу, что недостаточно хорошо понимаю принципы вложения Python. Я что-то упускаю очевидный.

Я нашел несколько примеров встраивания диаграмм matplotlib в PyQt или PySide (т. е. написанные на Python) приложения, где я видел что-то вроде QMainWindow.setCentralWidget(холст) или макет.addWidget (холст). Здесь canvas-объект FigureCanvasQTAgg (http://matplotlib.org/api/backend_qt4agg_api.html).

это предполагает, что canvas наследуется от QWidget. Но когда я пытаюсь имитировать это в коде C++, используя C API Python, я заканчиваю только PyObject * холст, не зная, как преобразовать его в QWidget. Это мой фрагмент без важного шага:

//draw a figure in Python script called from C++ app
PyRun_SimpleString("import matplotlibn"
"matplotlib.use('Qt4agg')n" //use Qt4 backend
"import pylabn"
"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 ответов


для PySide, я предлагаю прочитать этот комп.движение за освобождение.кварта.pyside thread и в разделе преобразователи типа в документах PySide. Я не могу поручиться за абсолютную правильность код, но, похоже, он делает то, что вы хотите.

Для PyQt, тот же комп.движение за освобождение.кварта.pyside thread ссылки на пример разворачивание объектов SIP что опять-таки именно то, что вам нужно.