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:
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):
Is this a known issue, am I doing anything wrong or did I discover a new bug?
-
Hi,
Can you provide a minimal compilable example that shows this behaviour ?
-
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):
#------------------------------------------------- # # 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>
-
Sorry, I don't have the XPS printer available. Can you check whether you have the same result with the QPdfWriter class ?