【问题标题】:Qt Charts rendering problems on a PDFPDF 上的 Qt 图表呈现问题
【发布时间】:2014-12-17 16:36:40
【问题描述】:

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

问题出在这里

  • 由于某种未知原因,图表需要在呈现为 PDF 之前显示为 show() 以使其大小正常(左图)。

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

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

在呈现为 PDF 之前在窗口上显示所有图表不是一种选择。图表需要执行show() 以使 QPainter 正确地将其绘制到 PDF 的事实似乎表明没有它,QPainter 会忽略图表的维度。

附带说明,show() 打开窗口,但需要几秒钟 图表要出现,所以渲染非常非常慢,这是我不想显示图表的另一个原因。

以下是我的主要问题:

  • 是这些错误还是我遗漏了什么?
  • 如果不是,那么指定绘图的大小和 (x,y) 位置的正确方法是什么(在 PDF)?

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

ma​​in.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

【问题讨论】:

    标签: c++ qt pdf charts qpainter


    【解决方案1】:

    绕过这个问题的一种方法是从QChartView 创建一个QPixmap 并将像素图绘制到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 中绘图的大小和位置。这并不理想,但现在可以。我知道,这是一个 hack,它有效,但我仍在寻找更好的解决方案。

    【讨论】:

      【解决方案2】:

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

      有关示例代码,请在此处查看我的其他答案:QTextDocument, QPdfWriter - how to scale output

      【讨论】:

      • 谢谢,感谢您的努力。我稍后会对此进行测试。我最终想出了另一种方法来解决这个问题。
      【解决方案3】:

      我发现抓取像素图并不好,因为它可能看起来不太好或分辨率不好。但是,您可以这样做:

      chartView->grab(); chartView->render (&painter, ...等

      chartView 是一个 QChartView 对象。然后画家正确地渲染图表。它与 show() 一样有效,但您不必在 GUI 中显示图表。显然,grab() 和 show() 都会导致图表在内部呈现并以某种方式解决 Qt 错误。

      【讨论】:

        猜你喜欢
        • 2012-04-18
        • 1970-01-01
        • 1970-01-01
        • 2011-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-03
        相关资源
        最近更新 更多