Qt图表在PDF上呈现问题

时间:2014-12-17 16:36:40

标签: c++ qt pdf charts qpainter

我正在使用Qt charts模块直接在PDF文件上绘制pie chart

以下是问题

  • 由于某些未知原因,图表需要与show()一起显示才能呈现给PDF,因为它的大小合适(左图)。

  • 另一方面,我不想在屏幕上显示每个图表,因为我的应用程序会生成很多图表。 但是,如果图表没有显示在show()的窗口中,那么即使使用{正确设置图表的大小,PDF中的图形也会变得太小(右图) {1}}。

(为这些图像添加了黑色边框以改善可视化效果)

在窗口上呈现所有图表,然后再将它们呈现给PDF不是一种选择。图表需要为QPainter执行resize()以正确地将其绘制到PDF这一事实似乎表明,如果没有它,QPainter将忽略图表的维度。

在旁注上,show()打开窗口,但需要几秒钟 要显示的图表,因此渲染非常慢,这是我不想显示图表的另一个原因。

所以这是我的主要问题:

  • 这些错误还是我错过了什么?
  • 如果没有,那么指定图纸的尺寸和(x,y)位置的正确方法是什么? PDF)?

这是Minimal, Complete, and Verifiable example ...

的main.cpp

show()

QtCharts_PDF.pro

#include <QApplication>
#include <QtCharts/QChartView>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QPainter>
#include <QPdfWriter>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QtCharts::QChartView* chartView = new QtCharts::QChartView();
    chartView->setRenderHint(QPainter::Antialiasing);
    chartView->resize(640, 480);

    QtCharts::QChart* chart = chartView->chart();
    chart->setTitle("Beautiful Pie Chart");
    chart->legend()->hide();

    QtCharts::QPieSeries* series = new QtCharts::QPieSeries();
    float hits = 73.0f, misses = 27.0f;
    series->append("Hits", hits);
    series->append("Misses", misses);

    QtCharts::QPieSlice* hit_slice = series->slices().at(0);
    hit_slice->setBrush(QColor(87, 147, 243));  // blue

    QtCharts::QPieSlice* miss_slice = series->slices().at(1);
    miss_slice->setBrush(QColor(221, 68, 68)); // red

    chart->addSeries(series);

    // Due to Qt bug, must show() the chart before render()
    // or it will be draw too tiny in the PDF by QPainter
    chartView->show();

    QPdfWriter writer("out.pdf");
    writer.setCreator("https://stackoverflow.com/users/176769/karlphillip");
    writer.setPageSize(QPagedPaintDevice::A4);
    QPainter painter(&writer);

    chartView->render(&painter);

    painter.end();

    return a.exec();
}

2 个答案:

答案 0 :(得分:7)

绕过此问题的一种方法是从QPixmap创建QChartView并将像素图绘制到PDF中:

    QPixmap pix = chartView->grab();
    int h = painter.window().height()*0.4;
    int w = h * 1.3;
    int x = (painter.window().width() / 2) - (w/2);
    int y = (painter.window().height() / 2) - (h/2);
    chartView->resize(w, h);
    painter.drawPixmap(x, y, w, h, pix);

这有点像拍摄小部件的屏幕截图并将其呈现到文件中。

QPainter.drawPixmap()让我们在PDF中指定绘图的大小和位置。这不是理想的,但它现在会做。我知道,这是一个黑客,它有效,但我仍在寻找更好的解决方案。

答案 1 :(得分:2)

我认为这可能是一个扩展问题,因为我遇到了类似的问题,我的输出打印比预期的要小得多。 QPdfWriter的逻辑单位为“点”,默认分辨率为每英寸1200点。您需要决定如何在QChartView的大小和其打印外观之间进行映射。默认情况下,QPdfWriter会将像素映射到点。您希望将缩放设置为1200/pixelsPerInch

有关示例代码,请参阅我的其他答案:QTextDocument, QPdfWriter - how to scale output