Qt图表在PDF上呈现问题

kar*_*lip 11 c++ pdf charts qt qpainter

我正在使用Qt charts模块直接在PDF文件上绘制饼图.

这是问题所在:

  • 由于某些未知原因,图表需要show()在呈现给PDF之前显示,因为它的大小正常(左图).

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

(在这些图像中添加了黑色边框以改善可视化)

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

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

所以这是我的主要问题:

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

这是一个最小的,完整的,可验证的例子 ......

main.cpp:

#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();
}
Run Code Online (Sandbox Code Playgroud)

QtCharts_PDF.pro:

QT       += core gui charts

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QtCharts_PDF
TEMPLATE = app
SOURCES += main.cpp
Run Code Online (Sandbox Code Playgroud)

kar*_*lip 7

绕过这个问题的方法是创建一个QPixmapQChartView并绘制像素映射到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);
Run Code Online (Sandbox Code Playgroud)

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

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