PDA

View Full Version : Bug in Qt5.12 or PyQt5.11.3???



barkowski@shinobi-mail.de
19th January 2019, 15:52
Hey there!

I have a problem with PyQt5 and QPrinter which seems to be related to PyQt 5.11.3 or Qt 5.12. I’m running Manjaro Linux (Kenel 4.20) with python 3.7.2, pyqt5-common 5.11.3, python-pyqt5 5.11.3 and Qt5 at v5.12.0.
(The problem occurs also in openSuse Tumbleweed. It seems, that it is not specific to Manjaro or Arch Linux)

I have a program which printed directly to a pdf-file in portrait- or landscape-orientation using QPrinter. Everything worked perfectly with PyQt5 v5.11.2 and Qt5 v5.11.2.
But now after update to Qt5.12 and pyqt5.11.3, whitout any code-changes, I always get documents in format "us-letter" in portrait-orientation.

I have a minimal working-example and some pdf-files to illustrate this here: https://www.dropbox.com/sh/feve6ubvylrko0x/AACC8W0hqEQWSu3t5zGdQI9ra?dl=0
(I had to remove names in two of the documents with LibreOffice Draw. Thus, the specs say that they are generated by LibreOffice instead of Qt5.12.)

In my example script, I let python print the printer-settings and they are correct, but the generated output is wrong.

Can anybody confirm and reproduce this behaviour with my working example?

Thank you!

Regards,

Sam Barkowski

Here is a working example in a Code-Tag:



from decimal import Decimal
import os
import sys
import platform
import tempfile
from PyQt5.QtWidgets import QWidget, QToolTip, QPushButton, QApplication
from PyQt5.QtGui import QPainter, QFont, QDesktopServices, QPen, QColor, QTextOption, QPageLayout, QPageSize
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
from PyQt5.QtCore import Qt, QUrl, QRectF, QMarginsF, QSizeF

class Example(QWidget):

def __init__(self):
super().__init__()
self.initUI()
self.printer = QPrinter(300) # QPrinter.HighResolution
self.printer.setPageSize(QPrinter.A4)
self.printer.setOutputFormat(QPrinter.PdfFormat)
print("Printercheck1:", self.printer.isValid())
self.tempdir = tempfile.mkdtemp(prefix="PyTesting-")
self._Windows = False
if platform.system() == "Windows":
self._Windows = True


def initUI(self):

QToolTip.setFont(QFont('SansSerif', 10))

self.setToolTip('Try printing')

btn = QPushButton('Print portrait-pdf', self)
btn.setToolTip('This should produce a PDF in portrait mode in A4 format')
btn.resize(btn.sizeHint())
btn.move(60, 50)
btn.clicked.connect(lambda:self.exPrint(pdf=True, lscp=False))

btn2 = QPushButton('Print landscape-pdf', self)
btn2.setToolTip('This should produce a PDF in landscape mode in A4 format')
btn2.resize(btn.sizeHint())
btn2.move(60, 100)
btn2.clicked.connect(lambda:self.exPrint(pdf=True, lscp=True))

btn3 = QPushButton('Print dialog portrait', self)
btn3.setToolTip('Open Print-Dialog portrait')
btn3.resize(btn.sizeHint())
btn3.move(60, 150)
btn3.clicked.connect(lambda:self.exPrint(pdf=False , lscp=False))

btn4 = QPushButton('Print dialog lscp', self)
btn4.setToolTip('Open Print-Dialog landscape')
btn4.resize(btn.sizeHint())
btn4.move(60, 200)
btn4.clicked.connect(lambda:self.exPrint(pdf=False , lscp=True))

self.setGeometry(400, 400, 400, 300)
self.setWindowTitle('Printing-Test')
self.show()

def printsettings(self, pdf=True, name="", landscp=False):
printservice = None
painter = None
filename = None
if pdf or self._Windows:
printservice = self.printer
if landscp:
try:
printservice.setPageOrientation(QPageLayout.Landsc ape)
print("Printercheck2:", printservice.isValid())
except Exception as e:
print("Exception in printersettings:", e.args[0])
else:
try:
printservice.setPageOrientation(QPageLayout.Portra it)
except Exception as e:
print("Exception in printersettings::", e.args[0])
print("Current settings:", printservice.pageLayout().pageSize().size(QPageSiz e.Millimeter), printservice.pageLayout().orientation())
if self._Windows:
slash = "\\"
else:
slash = "/"
filename = self.tempdir + slash + name + ".pdf"
self.printer.setOutputFileName(filename)
self.printer.setDocName(filename)
else:
filename = ""
printservice = QPrinter(300) # 300 QPrinter.HighResolution
printservice.setFullPage(True)
printservice.setPageSize(QPrinter.A4)
if landscp:
try:
printservice.setPageOrientation(QPageLayout.Landsc ape)
except Exception as e:
print("Exception in printersettings:", e.args[0])
else:
try:
printservice.setPageOrientation(QPageLayout.Portra it)
except Exception as e:
print("Exception in printersettings:", e.args[0])
dialog = QPrintDialog(printservice, None)
if not dialog.exec_():
return (None, None, None)
if printservice is not None:
painter = QPainter(printservice)
painter.setRenderHints(QPainter.TextAntialiasing)
painter.resetTransform()
scale = Decimal(1)
painter.scale(scale, scale)
return (printservice, painter, filename)

def finishjob(self, painter, filename, pdf=True):
painter.end()
if pdf:
url = QUrl.fromLocalFile(filename)
QDesktopServices.openUrl(url)
else:
if self._Windows:
try:
os.startfile(filename, "print")
except Exception as e:
print("Exception in attempt to print file:", filename, "ErrorMessage:", e.args[0])


def mm2pt(self, x):
"""used to calculate millimeters to point, for passing lengths in millimeter to the painter"""
if type(x) == float or type(x) == int:
return int(round(Decimal("360")/Decimal("127")*Decimal(x)))
else:
return None

def fromLeft(self, x):
"""distance from left paper edge in millimeters"""
return (self.mm2pt(x) - 18)

def fromTop(self, y):
"""distance from top edge of paper in millimeters"""
return (self.mm2pt(y) - 8)

def exPrint(self, pdf=True, lscp=False):
name = 'printingexample'
printmode = self.printsettings(pdf, name, lscp)
printservice = printmode[0]
painter = printmode[1]
filename = printmode[2]
if printservice is not None:
pen = QPen(QColor(0, 0, 0))
pen.setWidthF(0.4)
painter.setPen(pen)
sansFont = QFont("Sans Serif", 9, weight=45)
painter.setFont(sansFont)
x1 = self.fromLeft(17)
x2 = x1 + self.mm2pt(200)
t_left = QTextOption()
t_left.setAlignment(Qt.AlignLeft)
t_right = QTextOption()
t_right.setAlignment(Qt.AlignRight)
height = 12
rect = QRectF(x1, self.mm2pt(10), x2 - x1, 2*height)
painter.drawText(rect, "top left", t_left)
painter.drawText(rect, "top right", t_right)
try:
self.finishjob(painter, filename, pdf)
except (PermissionError, ProcessLookupError, FileExistsError, FileNotFoundError,
AttributeError, AssertionError, NotADirectoryError) as e:
print("Failed to open or print document. ErrorMessage:", e.args[0])
else:
print("Printservice not available.")

def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

if __name__ == "__main__":
main()

anda_skoa
26th January 2019, 09:11
Between the two libraries I would rather assume the responsibility in Qt than in the Python Wrapper.

Have you checked the printer's pageSize at the time of printing? Is it still set to A4 set by you in the constructor but not using it when generating?

Cheers,
_

barkowski@shinobi-mail.de
26th January 2019, 11:48
Hey anda_skoa,

thanks for your answer.

Yes, the pageSize is still set to A4.
This is also true when I try to print via printdialog (and not directly into a pdf-file). The settings are passed correctly, but I get wrong output with my HP printer and also when I print to pdf with the installed pdfprinter of my system.

I've also tried this with pySide2 (i. e. Qt for Python) and the result is the same.

anda_skoa
26th January 2019, 12:10
That sounds very much like a bug indeed.

Is it just wrong with A4 or does it always end using Letter even when you use any other different size?

Given that you experience this with portrait but not landscape, have you tried setting page size after page orientation?

You could also try QPdfWriter but I guess it will have the same problem (very likely sharing most of the implementation).

Cheers,
_

barkowski@shinobi-mail.de
26th January 2019, 14:08
The output is always in portrait and us-letter (setting landscape has no effect) and the wrong page dimensions are independent of the desired page orientation.
It is not depending on A4, too. Same result with othe page dimensions as A5 or A3.

Should I place a bug-report here: https://bugreports.qt.io/secure/Dashboard.jspa?

anda_skoa
27th January 2019, 10:21
The output is always in portrait and us-letter (setting landscape has no effect

Oh, wow, even worse than how I interpreted it.



Should I place a bug-report here: https://bugreports.qt.io/secure/Dashboard.jspa?

Yes, definitely.

I looked a bit and couldn't find a simlar report.

Ideally attach a minimal test program, e.g. using Qt for Python, that shows the problem.

Cheers,
_