Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Print Widget to PDF : Error with Icon



  • Hello,

    I try to print to PDF an entire widget that can contain multiple sort of widgets.
    The widget to be printed is a tab contained in a QTabWidget.

    Here is the code that tries to print :

    void MainWindow::print()
    {
        quint8 tabIndex = quint8(ui->tabWidget->currentIndex());
        CharacterSheetWidget* widget = dynamic_cast< CharacterSheetWidget* >( ui->tabWidget->widget(tabIndex) );
        QString tabName = ui->tabWidget->tabText(tabIndex);
        QString filePath = QFileDialog::getSaveFileName(this, QString(tr("Print as PDF...")), tabName, "PDF file (*.pdf)");
    
        if(filePath.isEmpty())
            return;
    
        QPrinter printer;
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName(filePath);
        printer.setPaperSize(QPrinter::A4);
        printer.setResolution(300);
        printer.setFullPage(false);
        printer.setPageMargins(5, 5, 5, 5, QPrinter::Millimeter);
    
        QString originalStyle = widget->styleSheet();
        widget->setStyleSheet("background-color:white;");
    
        QPainter painter;
        painter.begin(&printer);
        double xscale = printer.pageRect().width() / double(widget->width());
        double yscale = printer.pageRect().height() / double(widget->height());
        double scale = qMin(xscale, yscale);
        painter.translate(printer.paperRect().center());
        painter.scale(scale, scale);
        painter.translate(- widget->width()/ 2, - widget->height()/ 2);
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
        widget->render(&painter);
        painter.end();
        widget->setStyleSheet(originalStyle);
    }
    

    As I said, the user can add multiple type of widgets.
    When the entire widget contains QLabel, QLineEdit, QSpinBox, and even QLabel with a QPixmap, the PDF is generated with no problem.
    Here is how I generate the QLabel with QPixmap (the print works)

            QPixmap pix;
            QByteArray bytes = QByteArray::fromBase64(info.imageFileData.toLatin1());
            pix.loadFromData(bytes, "PNG");
            if(!pix.isNull())
            {
                pix = pix.scaled(300, 100, Qt::KeepAspectRatio);
                displayWidget->ui->icon->setPixmap(QPixmap(pix));
            }
    

    info.imageFileData being a QString.

    So for the moment everything works.

    But, when the user add a QPushButton which contains an icon (icon file that is attributed to the QPushButton via Qt Designer : I added a ressource file, added the .png image, and browsed from Qt Designer to that png file under the property "icon" )
    ... the print crashes the program, I have a 0 ko pdf and this message :

    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
    terminate called after throwing an instance of 'std::bad_alloc'
      what():  std::bad_alloc
    

    by debugging, I see that it crash at "painter.end();" line

    what's wrong ?
    (if you need more information, please tell me)


  • Lifetime Qt Champion

    Please provide a minimal testcase so we can reproduce a crash. From a first pov it should not crash. Also which OS and Qt version do you use?



  • I just wrote a minimal testcase, with a lot of the same conditions from my code, but the print is doin' good.
    I don't know what to do ... ?

    Windows 10,Qt 5.13.2



  • Ok, I clean the project, run qmake, recompile and it works...

    solved


Log in to reply