Issue with QPainter, opacity and multiline text



  • I'm using Qt 5.9.1 and I'm having an issue trying to draw a watermark-style text using QPainter.

    I did not find any open bug related to this but I'm not very familiar with the searching options so I might have missed it.

    If the underlying device is a QWidget the text is correctly drawn, but if the device is a QPrinter the first line of text always ignores the Opacity. Below is the smallest snippet I could cook that reproduces the issue.

    QString		watermarkText	("Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark");
    QRect		painterRect			(0,0,painter.device()->width(),painter.device()->height());
    
    	painter.setOpacity(0.5);		
    	painter.drawText(painterRect,watermarkText);
    

    I'm using a long text and relying on word wrap, but the same happens if I use newlines.

    This is the output on a QWidget:

    QWidget

    And this is the output on a printer ( Foxit PDF Printer in this case, but I have also tested with Microsoft XPS Document Writer and my Epson paper printer with the same result):

    QWidget

    Is this a known issue, am I doing anything wrong or did I discover a new bug?


  • Lifetime Qt Champion

    Hi,

    Can you provide a minimal compilable example that shows this behaviour ?



  • Sure, I don't know if this is the best way to post it (if it's not, tell what is please) but here is what I'm using:

    EDIT: see below.


  • Lifetime Qt Champion

    You are missing the .ui and the .pro file



  • I'm sorry, I was assuming everyone has the same environment as me., so the remaining files were just the automatically generated ones.

    Since we're at it, I am using Visual Studio 2017 (15.0) on Windows 10 (64-bit) but my application is 32-bit, if any of it matters.

    Here is my sample in Qt Creator 4.7.0 (please disregard the previous files):

    QtGuiApplication1.pro:

    #-------------------------------------------------
    #
    # Project created by QtCreator 2018-09-03T22:12:56
    #
    #-------------------------------------------------
    
    QT       += core gui widgets printsupport
    
    TARGET = QtGuiApplication1
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    CONFIG += c++11
    
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            mainwindow.h
    
    FORMS += \
            mainwindow.ui
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    

    main.cpp:

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        bool eventFilter(QObject *obj, QEvent *event);
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QPainter>
    #include <QPrinter>
    #include <QDebug>
    #include <QPrinterInfo>
    
    void	draw(QPainter& painter)
    {
    QString		watermarkTextTiled	("Watermark\nWatermark");
    QRect		painterRect			(0,0,painter.device()->width(),painter.device()->height());
    QTextOption textOption;
    
            textOption.setWrapMode(QTextOption::NoWrap);
    
            painter.setOpacity(0.5);
            painter.drawText(painterRect,watermarkTextTiled);
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        ui->centralWidget->installEventFilter(this);
    
        QPrinter printer(QPrinterInfo::printerInfo("Microsoft XPS Document Writer"));
    
        QPainter painter(&printer);
    
        draw(painter);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        if (event->type() == QEvent::Paint)
        {
        QPainter painter(ui->centralWidget);
    
            draw(painter);
    
            return(true);
        }
        return QObject::eventFilter(obj, event);
    }
    
    

    mainwindow.ui:

    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow" >
      <property name="geometry" >
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle" >
       <string>MainWindow</string>
      </property>
      <widget class="QMenuBar" name="menuBar" />
      <widget class="QToolBar" name="mainToolBar" />
      <widget class="QWidget" name="centralWidget" />
      <widget class="QStatusBar" name="statusBar" />
     </widget>
     <layoutDefault spacing="6" margin="11" />
     <pixmapfunction></pixmapfunction>
     <resources/>
     <connections/>
    </ui>
    
    

  • Lifetime Qt Champion

    Sorry, I don't have the XPS printer available. Can you check whether you have the same result with the QPdfWriter class ?