2014-12-17 11 views
9

Uso il modulo Qt charts per disegnare un pie chart direttamente su un file PDF.Qt Problemi di rendering dei grafici su un PDF

Ecco il problema:

  • Per qualche ragione sconosciuta, il grafico deve essere visualizzato con show() prima che sia reso al PDF per la sua dimensione per essere OK (immagine a sinistra).

  • D'altra parte, non voglio dover visualizzare tutti i grafici sullo schermo poiché la mia applicazione ne genera molti. Tuttavia,, se il grafico non viene visualizzato in una finestra con show(), il disegno diventa troppo piccolo nel PDF (immagine a destra) anche se la dimensione del grafico è impostata correttamente con resize().

(bordi neri sono stati aggiunti a queste immagini per migliorare la visualizzazione)

Visualizzazione tutti i grafici su una finestra prima che vengano resi al PDF non è un'opzione. Il fatto che il grafico debba eseguire show() per QPainter per disegnarlo correttamente nel PDF sembra indicare che senza di esso, QPainter ignora le dimensioni del grafico.

Su un lato nota, show() apre la finestra, ma ci vogliono parecchi secondi per il grafico appaia, quindi il rendering è molto molto lento, un altro motivo per me di non voler visualizzare i grafici.

Così qui sono le mie domande principali:

  • Sono questi bug o mi sto perdendo qualcosa?
  • In caso contrario, quale sarebbe il modo corretto per specificare la dimensione e la posizione (x, y) del disegno (nel documento PDF )?

Ecco un 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 

risposta

5

Un modo per aggirare questo problema è creare un QPixmap da il QChartView e disegnare la mappa di pixel in formato 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); 

Questo è un po 'come prendere uno screenshot del widget e rendendola al file.

QPainter.drawPixmap() Si specifica la dimensione e la posizione del disegno nel PDF.Non è l'ideale, ma lo farà per ora. Lo so, è un trucco, funziona, ma sto ancora cercando una soluzione migliore.

1

Penso che questo potrebbe essere un problema di ridimensionamento in quanto ho riscontrato un problema simile con il mio output stampato molto più piccolo del previsto. QPdfWriter ha un'unità logica di un "punto" in cui la risoluzione predefinita è di 1200 punti per pollice. È necessario decidere come eseguire il mapping tra la dimensione di QChartView e il suo aspetto stampato. Il QPdfWriter mapperà un pixel in un punto per impostazione predefinita. Si desidera impostare un ridimensionamento di 1200/pixelsPerInch

Per codice di esempio vedere la mia altra risposta qui: QTextDocument, QPdfWriter - how to scale output

+0

Grazie, apprezzo lo sforzo. Lo metterò alla prova più tardi. Ho finito per capire un altro modo per affrontare questo. – karlphillip

Problemi correlati