2014-12-17 5 views
9

Ich verwende Qt charts Modul, um eine pie chart direkt in eine PDF-Datei zu zeichnen.Qt Charts Rendering Probleme auf einem PDF

Hier ist das Problem:

  • Aus unbekannten Gründen muss das Diagramm mit show() angezeigt werden, bevor es für seine Größe auf die PDF gerendert ist OK (linkes Bild) zu sein.

  • Auf der anderen Seite möchte ich nicht jedes Diagramm auf dem Bildschirm anzeigen müssen, da meine Anwendung eine Menge von ihnen generiert. Jedoch,, wenn das Diagramm nicht in einem Fenster mit show() angezeigt wird, dann wird die Zeichnung in der PDF zu klein (rechtes Bild), obwohl die Größe des Diagramms ordnungsgemäß mit resize() festgelegt ist.

(schwarze Ränder wurden auf diese Bilder hinzugefügt Visualisierung zu verbessern)

Anzeige aller Diagramme auf einem Fenster, bevor sie in das PDF gerendert werden keine Option ist. Die Tatsache, dass das Diagramm show() für QPainter ausführen muss, um es korrekt in das PDF zu zeichnen, scheint darauf hinzudeuten, dass QPainter die Dimension des Diagramms ignoriert.

show() öffnet das Fenster, aber es dauert einige Sekunden für das Diagramm erscheinen, so Rendering ist sehr, sehr langsam, ein weiterer Grund für mich, die Diagramme nicht anzuzeigen.

hier sind also meine Hauptfragen:

  • diese Fehler oder ich etwas fehle?
  • Wenn nicht, was wäre der richtige Weg, um die Größe und (x, y) Position der Zeichnung (in der PDF) zu spezifizieren? Hier

ist ein Minimal, Complete, and Verifiable example ...

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 

Antwort

5

Eine Möglichkeit, dieses Problem zu umgehen, ist um eine QPixmap aus zu erstellen die QChartView und die Pixmap in das PDF ziehen:

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); 

Dies ist ein bisschen wie ein Screenshot des Widgets zu nehmen und ihn in die Datei zu machen.

QPainter.drawPixmap() können Sie die Größe und Position der Zeichnung im PDF angeben.Es ist nicht ideal, aber es wird für jetzt tun. Ich weiß, es ist ein Hack, es funktioniert, aber ich suche immer noch nach einer besseren Lösung.

1

Ich denke, dies könnte ein Skalierungsproblem sein, da ich ein ähnliches Problem mit meiner Ausgabe, die viel kleiner als erwartet gedruckt wurde, festgestellt habe. QPdfWriter hat eine logische Einheit eines "Punktes", wobei die Standardauflösung 1200 Punkte pro Zoll beträgt. Sie müssen entscheiden, wie Sie zwischen der Größe von QChartView und seiner gedruckten Darstellung mappen. Die QPdfWriter wird ein Pixel standardmäßig einem Punkt zuordnen. Sie möchten eine Skalierung von Code 1200/pixelsPerInch

Für die Probe setzen meine andere Antwort siehe hier: QTextDocument, QPdfWriter - how to scale output

+0

Danke, ich die Mühe zu schätzen wissen. Ich werde das später testen. Ich habe einen anderen Weg gefunden, damit umzugehen. – karlphillip