Проблемы рендеринга диаграмм Qt в формате PDF

я использую 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();
}

QtCharts_PDF.pro:

QT       += core gui charts

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QtCharts_PDF
TEMPLATE = app
SOURCES += main.cpp

2 ответов


один из способов обойти эту проблему является создание QPixmap С QChartView и нарисуйте pixmap в 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. Это не идеально, но пока сойдет. Я знаю, что это хак, он работает, но я все еще ищу лучшее решение.


Я думаю, что это может быть проблема масштабирования, поскольку я столкнулся с аналогичной проблемой, когда мой вывод был напечатан намного меньше, чем ожидалось. QPdfWriter имеет логическую единицу "точка", где по умолчанию разрешение составляет 1200 точек на дюйм. Вам нужно решить, как сопоставить размер QChartView и его печатный вид. The QPdfWriter будет сопоставлять пиксель с точкой по умолчанию. Вы хотите установить масштабирование 1200/pixelsPerInch

пример кода, см. Мой другой ответ здесь: QTextDocument, QPdfWriter-как масштабировать вывод