2016-08-06 14 views
1

具体的なペインタにQChart(コアにはQGraphicsWidget)をレンダリングしたいとします。たとえば、QSvgGeneratorです。QGraphicsViewを使用しないでQChartをレンダリングする

私は、トピックhttps://forum.qt.io/topic/38352/rendering-qgraphicsitem-without-qgraphicsscene/2次読んで、私のコードでそれを実装しました:最初の1が第二、直接QChartを描くためである - QGraphicsViewレンダリング:

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

コメントを持つ2つの行があります。

私は既にsetViewBoxでプレイしようとしましたが、それを巨大な値に設定することは役に立ちません。 QSvgGeneratorの代わりにQImageを使用した場合の効果は同じですが、空の画像が表示されます。

質問はなぜQChart->paint()私に空の絵を与えるのですか?

EDIT:作業コードはビットバケットに見つけることができる:https://bitbucket.org/morodeer/charts_test_2/commits/b1eee99736beb5e43eae2a40ae116ee07e01558f

答えて

2

私はまだコアに深く何が起こっているか理解していないが、私はそれを動作させるための方法を見つけました。

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

、そしてあなたは、チャートのシーンをレンダリングできるようになります。

+0

ありがとうございます。これは多くの助けとなりました。 – Waldemar

0

これは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を使用している場合、ちょうどより多くの機能やフォーマットを提供し、また、PyQtは、GUIに統合することができますmatplotlibの、と行く方が簡単かもしれません。

+0

共有いただきありがとうございます。本当にあなたのソリューションは承認されたものを繰り返します。重要なのは、チャート自体ではなく、チャートの「シーン」をレンダリングすることです。 – ProdoElmit

関連する問題