[Interest] painter.fillRect() with gradient on PDF printer produces all white?

Israel Brewster ijbrewster at alaska.edu
Thu Apr 7 23:53:31 CEST 2022


On Apr 7, 2022, at 1:43 PM, Henry Skoglund <henry at tungware.se> wrote:
> 
> On 2022-04-07 23:08, Israel Brewster wrote:
>> On Apr 7, 2022, at 12:59 PM, Henry Skoglund <henry at tungware.se <mailto:henry at tungware.se>> wrote:
>>> 
>>> On 2022-04-07 22:04, Israel Brewster wrote:
>>>> On Apr 7, 2022, at 11:58 AM, Henry Skoglund <henry at tungware.se <mailto:henry at tungware.se>> wrote:
>>>>> On 2022-04-07 20:28, Israel Brewster wrote:
>>>>>> Using Qt 5.15 and PySide2, I am working on a project that requires me to produce a PDF output. My process so far is to create a QWidget containing the content I want, render it to a QPicture (so it won’t be rasterized upon “printing”), then create a PDF QPrinter and use the painter.drawPicture() function to “print” the widget into a PDF.
>>>>>> 
>>>>>> This works well, giving me a high-quality vectorized PDF output, with one exception: any item that is filled with a gradient. When printing to PDF, the gradient always comes out as solid white. With some digging, I determined that this is even the case when doing nothing but a simple painter.fillRect() with a gradient.
>>>>>> 
>>>>>> Is there any “fix” for this? Thanks.
>>>>>> 
>>>>>> If it helps, here is some simple code that reproduces the issue:
>>>>>> 
>>>>>> from PySide2.QtWidgets import QApplication
>>>>>> from PySide2.QtGui import QPainter, QPageSize, QLinearGradient
>>>>>> from PySide2.QtPrintSupport import QPrinter
>>>>>> from PySide2.QtCore import QSize, QRect, Qt
>>>>>> 
>>>>>> app = QApplication()
>>>>>> 
>>>>>> gradient_rect = QRect(0, 0, 500, 25)
>>>>>> gradient = QLinearGradient(0, 0, 1, 0)
>>>>>> gradient.setColorAt(0, Qt.blue)
>>>>>> gradient.setColorAt(1, Qt.red)
>>>>>> 
>>>>>> page_size = QPageSize(QSize(500, 25), matchPolicy = QPageSize.ExactMatch)
>>>>>> printer = QPrinter()
>>>>>> printer.setOutputFormat(QPrinter.PdfFormat)
>>>>>> printer.setPageSize(page_size)
>>>>>> printer.setOutputFileName('/tmp/testPDFGradient.pdf')
>>>>>> 
>>>>>> painter = QPainter(printer)
>>>>>> painter.fillRect(gradient_rect, gradient)
>>>>>> painter.end()
>>>>>> 
>>>>> Hi, try
>>>>> ...
>>>>> gradient_rect = QRect(0, 0, 500, 25)
>>>>> gradient = QLinearGradient(0, 0, 500, 25)
>>>>> gradient.setColorAt(0, Qt.blue)
>>>>> gradient.setColorAt(1, Qt.red)
>>>>> ...
>>>>> (i.e. QLinearGradient's ctor expects coords)
>>>> No change. The 1 value was picked because that’s what displays correctly in testing, but even with the suggested change I still get a solid white box.
>>>> 
>>> Hmm, I just tested on Ubuntu 20.04, created an empty vanilla widget program in Qt 5.15.2. added "printsupport" to the .pro file and changed mainwindow.cpp to look like this:
>>> 
>>> #include "mainwindow.h"
>>> #include "ui_mainwindow.h"
>>> #include "QtPrintSupport"
>>> 
>>> MainWindow::MainWindow(QWidget *parent)
>>>     : QMainWindow(parent)
>>>     , ui(new Ui::MainWindow)
>>> {
>>>     ui->setupUi(this);
>>> 
>>>     auto gradient_rect = QRect(0,0,500,25);
>>>     auto gradient = QLinearGradient(0,0,500,25);
>>>     gradient.setColorAt(0,Qt::blue);
>>>     gradient.setColorAt(1,Qt::red);
>>> 
>>>     QPrinter printer;
>>>     QPageSize ps(QSize(500,25),"GradientTest",QPageSize::ExactMatch);
>>>     printer.setOutputFormat(QPrinter::PdfFormat);
>>>     printer.setPageSize(ps);
>>> printer.setOutputFileName("/home/henry/Downloads/testPDFGradient.pdf");
>>> 
>>>     QPainter painter;
>>>     painter.begin(&printer);
>>>     painter.fillRect(gradient_rect,gradient);
>>>     painter.end();
>>> }
>>> 
>>> MainWindow::~MainWindow()
>>> {
>>>     delete ui;
>>> }
>>> 
>>> screenshot here: https://tungware.se/GradientOnUbuntu.png <https://tungware.se/GradientOnUbuntu.png>
>>> (also tested on Windows 10 MSVC2019 Qt 5.15.2 and works there as well)
>>> 
>>> Maybe pySide2 messes up something, you could try with some C++ :-)
>> 
>> Interesting…must be a MacOS thing then. I just tried your C++ code with the exact same results - plain white rectangle. So the only difference I can see now is that you tested on Windows and Linux, while I am testing on MacOS.
>> 
>> Wonderfull. Now I apparently need different code depending on which OS I am running on (assuming I can get this to work on MacOS at all)...
>> ---
>> 
> I fired up my Mac, tested my code above on Qt 6.2.4 and verified I got the same "A whiter shade of pale" as you.
> 
> Then I tested by copying a working .pdf from Ubuntu into Monterey, it also displayed as totally white (when double-clicked or when viewed in Safari).
> But when I copied the .PDF generated in Monterey into Ubuntu, guess what: it displayed correctly.
> 
> But it gets better! Guess what happens if you choose to view the PDF on Monterey with either Chrome or Firefox (instead of Safari), then the blue-red gradient lights up, yes even on the Mac :-)
> 
> Interesting, right?
> 

Huh. I…well. Huh.

Ok, it’s official. Time for me to hang up my software developer hat and sign up for a stay at the funny farm :-P

Shows up correctly in Acrobat reader as well, so I guess the issue is in the PDF renderer that Apple uses for Safari and Preview? Wow.

Excuse me while I run screaming off the nearest cliff… :-D

Thanks for helping track that down!
---
Israel Brewster
Software Engineer
Alaska Volcano Observatory 
Geophysical Institute - UAF 
2156 Koyukuk Drive 
Fairbanks AK 99775-7320
Work: 907-474-5172
cell:  907-328-9145

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20220407/948eac50/attachment.htm>


More information about the Interest mailing list