【问题标题】:Rendering QChart without QGraphicsView在没有 QGraphicsView 的情况下渲染 QChart
【发布时间】:2017-08-07 18:42:48
【问题描述】:

我想将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);

cmets 有两行:第一行用于直接绘制QChart,第二行-渲染QGraphicsView

我已经尝试过使用setViewBox,将其设置为巨大的值并没有帮助。如果我使用QImage 而不是QSvgGenerator,效果是一样的,我得到的是空白图片。

所以问题是为什么QChart-&gt;paint() 给我空画?

编辑:可以在 bitbucket 上找到工作代码:https://bitbucket.org/morodeer/charts_test_2/commits/b1eee99736beb5e43eae2a40ae116ee07e01558f

【问题讨论】:

    标签: qt qtcharts


    【解决方案1】:

    我仍然不明白核心深处发生了什么,但我已经找到了让它发挥作用的方法。

    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);
    

    ,然后你就可以渲染图表的场景了。

    【讨论】:

      【解决方案2】:

      由于这或多或少是我发现的关于如何从 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 中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-10
        • 2018-04-13
        • 1970-01-01
        • 1970-01-01
        • 2019-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多