Search code examples
c++qtqt5qpainterqprinter

How to print multiple qwidgets to a pdf in different pages using Qpainter?


I'm trying to render qwidgets each in a separate page and save it in a pdf format. I tried using Qpainter, Qprinter and tried to render as suggested in the forum: http://doc.qt.io/qt-4.8/printing.html#printing-widgets

This is my sample code:

QPainter painter;
painter.begin(&printer);
for(int page = 0;page<no_of_pages;page++)
{
double xscale = printer.pageRect().width()/double(MyWidget[page]->width());
double yscale = printer.pageRect().height()/double(MyWidget[page]->height());
double scale = qMin(xscale, yscale);
painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,
printer.paperRect().y() + printer.pageRect().height()/2);
painter.scale(scale, scale);
painter.translate(-MyWidget[page]->width()/2, -MyWidget[page]->height()/2);
MyWidget[page]->render(&painter);
if(page!=(no_of_pages-1))
   printer.newPage();
}
painter.end();

When I execute the above code, pdf is generated with exact number of pages in it but only the first page is printed. When I checked the application output console, the following messages are printed:

QPainter::begin: Paint device returned engine == 0, type: 2
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::setWorldTransform: Painter not active
QWidget::render: Cannot render with an inactive painter
QPainter::end: Painter not active, aborted

I tried to google about these messages, but none of them are relevant to rendering qwidgets. Any help is appreciated. Thank you.


Solution

  • The problem is not that it does not print on the next page but the scale is not correct, you must reset all the transformations at the end of each iteration with resetTransform(). I prefer to save the widget in a QList <QWidget *>.

    QList <QWidget *> widgets;
    widgets.append({some widget});
    [...]
    
    QPrinter printer;
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setOutputFileName("printer.pdf");
    
    QPainter painter;
    
    if (! painter.begin(&printer)) { // failed to open file
        qWarning("failed to open file, is it writable?");
    }
    
    for(auto widget: w){
        if(widget){
            if(widget->width() > 0 && widget->height() >0 ){
    
                qreal xscale = 0.9*printer.pageRect().width()/qreal(widget->width());
                qreal yscale = 0.9*printer.pageRect().height()/qreal(widget->height());
    
                qreal scale = qMin(xscale, yscale);
    
                painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,
                                  printer.paperRect().y() + printer.pageRect().height()/2);
    
                painter.scale(scale, scale);
                painter.translate(-width()/2, -height()/2);
                widget->render(&painter);
                painter.resetTransform();
                if(widget != widgets.last())
                    printer.newPage();
            }
        }
    
    }
    painter.end();
    

    Observation: Set a factor of 0.9 so that the image is displayed in a more pleasant way.