Qt5 breaks rendering to pdf on Windows?



  • When I render a scene to a QPrinter set to PdfFormat, my QGraphicsItem subclass is rendered wrong on two counts:

    1. opacity appears to be 1.0, no matter what I set it to.
    2. With a QGradient, when I use setColorAt() to set the color to Qt::transparent, it uses black instead.

    Rendering the scene to a QGraphicsView works correctly. But my users need to output to pdf. Rendering to a pdf does not have these issues in Qt 4.8, so it seems like a regression in Qt 5 or I'm missing something I should be doing in Qt 5.

    I'm using Qt 5.6.1-1 on Windows 8.1 and Windows 10. Below is a sscce to illustrate the issues:
    Main.cpp

    #include <QtWidgets/QApplication>
    #include <QtPrintSupport/QPrinter>
    #include <QtWidgets/QGraphicsItem>
    #include <QtWidgets/QGraphicsScene>
    #include <QtWidgets/QFileDialog>
    #include <QtGui/QPainter>
    
    const qreal kGradientWidth = 25.0;
    
    // This class demonstrates the issues of rendering to pdf when opacity < 1 and gradient to transparent.
    class MyGraphicsItem : public QGraphicsItem {
    public:
      explicit MyGraphicsItem() {
        base_rect_ = QRectF(QPointF(150, 100), QPointF(250, 140));
      }
    
      virtual QRectF boundingRect() const {
        QRectF bounds = base_rect_.adjusted(-kGradientWidth,
                                            -kGradientWidth,
                                            kGradientWidth,
                                            kGradientWidth);
        return bounds;
      }
    
      virtual void paint(QPainter *painter,
                         const QStyleOptionGraphicsItem * /*option*/,
                         QWidget * /*widget*/)  {
        painter->save();
    
        qreal opacity = 0.3;
        painter->setOpacity(opacity); // seems to ignore the opacity setting!
        painter->setPen(Qt::NoPen);
    
        QColor item_color("#ffffff");  // white
    
        QRectF rect_to_paint =
            base_rect_.adjusted(0.0,
                                -kGradientWidth,
                                0.0,
                                kGradientWidth);
        QLinearGradient gradient(rect_to_paint.topLeft(), rect_to_paint.bottomLeft());
        qreal padding_percent = kGradientWidth / rect_to_paint.height();
        gradient.setColorAt(0.0, Qt::red);  // works fine
        gradient.setColorAt(padding_percent, item_color);
        gradient.setColorAt(1.0 - padding_percent, item_color);
        gradient.setColorAt(1.0, Qt::transparent);  // uses black instead of transparent!
    
        painter->setBrush(gradient);
        painter->drawRect(rect_to_paint);
    
        painter->restore();
      }
    
    private:
      QRectF base_rect_;
    };
    
    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      // Create the scene with my graphics item to illustrate the problems:
      //  1. opacity of .6 becomes opacity of 1 when rendered to pdf.
      //  2. gradient to transparent becomes gradient to black when rendered to pdf.
      QGraphicsScene *scene = new QGraphicsScene(0, 0, 400, 400);
      scene->addRect(30, 15, 300, 300, QPen(), QBrush(Qt::green));
      MyGraphicsItem *my_item = new MyGraphicsItem;
      scene->addItem(my_item);
    
      // Where to save the pdf?
      QString filter("PDF Document (*.pdf)");
      QString folder;
      folder = "Y:\\Downloads";
      QString pdf_file = QFileDialog::getSaveFileName(NULL,
                                                      "save pdf",
                                                      folder,
                                                      filter);
      if (!pdf_file.isEmpty()) {
        // Save the pdf.
        QPrinter *printer = new QPrinter();
        printer->setOutputFileName(pdf_file);
        printer->setOutputFormat(QPrinter::PdfFormat);
    
        QPainter painter(printer);
        scene->render(&painter);
      }
    
      return 0;
    }
    

    .pro:

    QT += core gui widgets printsupport
    #CONFIG += c++11
    
    TARGET = win_pdf_contrast_sscce
    CONFIG += console
    CONFIG -= app_bundle
    
    TEMPLATE = app
    
    SOURCES += main.cpp
    

    What are my options for outputting my QGraphicsScene to a .pdf from a Qt 5.6.x app in Windows, in such a way that the opacity and gradient issues are resolved? Is there a workaround, a patch, or something I'm missing...?

    Thanks,
    David


  • Lifetime Qt Champion

    Hi,

    The printing system has changed in Qt 5 so you may have unearthed something. You should go to the bug report system to see if it's something known. If not please consider opening a new report providing your soccer.



  • I couldn't find any bugs that matched this, so I created this one.

    As a matter of procedure: should I paste the sample code into the bug report also, or is it better to just reference this topic as I did?


  • Lifetime Qt Champion

    Thanks for the report !

    The real best thing to do is to provide a zip file with the .pro and code files in it directly in the report. That way the developer taking a look at the bug can simply download, uncompress and start building. It's a level less of indirection and if for any reason the forum goes down, the bug can still be replicated.



  • ok, thanks for the guidance @SGaist - I have uploaded a .zip file in the bug report.



  • I created a fix for this issue and pasted the code into the bug report.


  • Lifetime Qt Champion

    Patches can not be taken like that from the bug tracker. Please create a submission through gerrit.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.