2016-08-06 16 views
1

Ich würde QChart (QGraphicsWidget in seinem Kern) zu bestimmten Maler, QSvgGenerator Rendern Rendern.Rendering QChart ohne QGraphicsView

Ich habe https://forum.qt.io/topic/38352/rendering-qgraphicsitem-without-qgraphicsscene/2 folgendes Thema gelesen und implementiert sie in meinem Code:

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

Es gibt zwei Linien mit Kommentaren: erste ist QChart direkt für die Malerei, die zweite - Rendering QGraphicsView.

Ich habe schon versucht, mit setViewBox zu spielen, die Einstellung auf enorme Werte hilft nicht. Der Effekt ist der gleiche, wenn ich QImage statt QSvgGenerator verwende, bekomme ich ein leeres Bild. Die Frage ist warum QChart->paint() mir leere Malerei gibt?

EDIT: https://bitbucket.org/morodeer/charts_test_2/commits/b1eee99736beb5e43eae2a40ae116ee07e01558f

Antwort

2

ich immer noch nicht verstehen, was passiert ist tief in Kern, aber ich habe einen Weg, damit es funktioniert gefunden: Arbeitscode kann auf bitbucket finden.

app->chart()->paint(&painter, 0, 0); 

sollte

app->chart()->scene()->render(&painter, 0, 0); 

enthält nichts wirklich im Inneren davon, aber fügt Elemente Eltern Szene Sieht aus wie QChart geändert werden. So, wenn Sie es machen müssen, ohne das Hinzufügen zu QGraphicsView wie ich, sollten Sie auch QGraphicsScene erstellen und fügen Sie Diagramm, um es:

m_scene = new QGraphicsScene(); 
m_scene->addItem(m_chart); 

, dann werden Sie in der Lage sein, Chart-Szene zu machen.

+0

Danke Mann. Das hat sehr geholfen. – Waldemar

0

Da dies mehr oder weniger der einzige Hinweis darauf ist, wie man Diagramme aus einem QChart überhaupt rendert und es eine Weile gedauert hat, bis ich es herausgefunden habe, musste ich meinen Code teilen.

Dies ist Python mit PyQt5, sollte aber leicht zu reinem C++ übersetzbar sein;) Beachten Sie auch, dass mein QChart Teil eines QChartView-Widget ist.

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) 

Aber wenn Sie Python verwenden könnte es einfacher sein, nur mit matplotlib zu gehen, die viel mehr Funktionen und Formate bieten und kann auch in einen PyQt-GUI integriert werden.

+0

Danke für die Freigabe. Wirklich wiederholt Ihre Lösung ein genehmigtes: das Schlüsselsache ist, Szene "des Diagramms", nicht "Diagramm" selbst darzustellen. – ProdoElmit

Verwandte Themen