我想将QChart (它的核心是QGraphicsWidget )呈现给特定的绘制器,例如QSvgGenerator。
我已经阅读了下面的主题https://forum.qt.io/topic/38352/rendering-qgraphicsitem-without-qgraphicsscene/2并在我的代码中实现了它:
QBuffer b;
QSvgGenerator p;
p.setOutputDevice(&b);
QSize s = app->chart()->size().toSize();
p.setSize(s);
p.setViewBox(QRect(0,0,s.width(),s.height()));
QPainter painter;
painter.begin(&p);
painter.setRenderHint(QPainter::Antialiasing);
app->chart()->paint(&painter, 0, 0); // This gives 0 items in 1 group
m_view->render(&painter); // m_view has app->chart() in it, and this one gives right image
qDebug() << "Copied";
painter.end();
QMimeData * d = new QMimeData();
d->setData("image/svg+xml",b.buffer());
QApplication::clipboard()->setMimeData(d,QClipboard::Clipboard);有两行注释:第一行用于直接绘制QChart,第二行用于呈现QGraphicsView。
我已经尝试过使用setViewBox,将其设置为巨大的值没有任何帮助。如果我使用QImage而不是QSvgGenerator,效果是一样的,我得到的是空图片。
所以问题是为什么QChart->paint()给了我空画?
编辑:工作代码可以在bitbucket上找到:https://bitbucket.org/morodeer/charts_test_2/commits/b1eee99736beb5e43eae2a40ae116ee07e01558f
发布于 2016-08-08 17:40:57
我仍然不明白核心内部到底发生了什么,但我已经找到了一种让它工作的方法。
app->chart()->paint(&painter, 0, 0); 应更改为
app->chart()->scene()->render(&painter, 0, 0);看起来QChart实际上并不包含任何内容,但会将项目添加到父场景中。因此,如果您需要像我一样在不添加到QGraphicsView的情况下呈现它,您还应该创建QGraphicsScene并向其中添加图表:
m_scene = new QGraphicsScene();
m_scene->addItem(m_chart);,然后您将能够渲染chart的场景。
发布于 2017-08-07 18:42:48
由于这或多或少是我找到的关于如何从QChart呈现图表的唯一提示,我花了很长时间才弄明白,我想我应该分享我的代码。
这是带有PyQt5的python,但是应该可以很容易地转换为纯C++ ;)还要注意,我的QChart是QChartView小部件的一部分。
chart = QtChart.QChart()
chart_view = QtChart.QChartView(chart)
...
# the desired size of the rendering
# in pixels for PNG, in pt for SVG
output_size = QtCore.QSize(800,600)
output_rect = QtCore.QRectF(QtCore.QPointF(0,0), QtCore.QSizeF(output_size)) # cast to float
if output_svg:
svg = QtSvg.QSvgGenerator()
svg.setFileName(filename)
svg.setTitle("some title")
svg.setSize(output_size)
svg.setViewBox(output_rect)
canvas = svg
else:
image = QtGui.QImage(output_size, QtGui.QImage.Format_ARGB32)
image.fill(QtCore.Qt.transparent)
canvas = image
# uncomment to hide background
#chart.setBackgroundBrush(brush = QtGui.QBrush(QtCore.Qt.NoBrush))
# resize the chart, as otherwise the size/scaling of the axes etc.
# will be dependent on the size of the chart in the GUI
# this way, a consistent output size is enforced
original_size = chart.size()
chart.resize(output_rect.size())
painter = QtGui.QPainter()
painter.begin(canvas)
# enable antialiasing (painter must be active, set this after painter.begin())
# only affects PNG output
painter.setRenderHint(QtGui.QPainter.Antialiasing)
chart.scene().render(painter, source=output_rect, target=output_rect, mode=QtCore.Qt.IgnoreAspectRatio)
painter.end()
chart.resize(original_size)
if type(canvas) == QtGui.QImage:
canvas.save(filename)但是如果您使用的是python,那么使用matplotlib可能会更容易一些,它提供了更多的特性和格式,并且还可以集成到PyQt-GUI中。
https://stackoverflow.com/questions/38800759
复制相似问题