2016-08-06 6 views
1

Я хотел бы сделать QChart (то есть QGraphicsWidget в своем ядре) конкретному художнику, например QSvgGenerator.Рендеринг QChart без QGraphicsView

Я прочитал следующую тему 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() дает мне пустую картину?

EDIT: рабочий код можно найти на BitBucket: 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, но его следует легко перевести на чистый 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) 

Но если вы используете питона может быть проще просто пойти с Matplotlib, который предлагает гораздо больше возможностей и форматов, а также может быть интегрирован в PyQt-GUI.

+0

Спасибо за обмен. На самом деле ваше решение повторяет одобренное: главное - отобразить «сцену» диаграммы, а не «диаграмму». – ProdoElmit