Results 1 to 4 of 4

Thread: PyQt5 QPrinting setFullpage doesn't works

  1. #1
    Join Date
    Aug 2017
    Posts
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default PyQt5 QPrinting setFullpage doesn't works

    Hi, newbie on the forums and also newbie at Qt programming.

    I am here because I have a problem, (which I researched for a fix and I am aware it's the same issue as This one on C++) and I can't find a way to fix on Python 3.5.

    The issue: When I try to print my widget to a PDF the result is this one:
    It should fit the entire A4 page but it resizes it to that small section (yeah, that red rectangle).
    MzSHRX75RRSmfkvcgucxLQ.jpg

    The code:
    Qt Code:
    1. from PyQt5.QtGui import QPainter
    2. from PyQt5.QtPrintSupport import QPrinter
    3.  
    4. # Print options
    5. printer = QPrinter(QPrinter.HighResolution)
    6. printer.setOrientation(QPrinter.Portrait)
    7. printer.setPaperSize(QPrinter.A4)
    8. printer.setPageSize(QPrinter.A4)
    9. printer.setPageMargins(15, 15, 15, 15, QPrinter.Millimeter)
    10. printer.setFullPage(True)
    11. printer.setOutputFormat(QPrinter.PdfFormat)
    12. printer.setOutputFileName("testfile.pdf")
    13.  
    14. # Render/Paint it
    15. painter = QPainter()
    16. painter.begin(printer)
    17. MyWidget.render(painter)
    18. painter.end()
    To copy to clipboard, switch view to plain text mode 

    Assuming This documentation is accurate, the setFullpage on true should fix it. so what am I missing?
    Last edited by Saelyth; 11th August 2017 at 19:07.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: PyQt5 QPrinting setFullpage doesn't works

    The setFullPage() function determines only whether Qt considers the entire page printable, or only that area the print device reports as printable (generally smaller). For a PDF virtual printer the two areas are the same.

    The size of the content put on the page is driven entirely by you, in this case MyWidget.render().
    The printer has a coordinate system that is device dependent. The addressable area of the page is represented by a rectangle you can query with QPrinter::pageRect(). Your widget has a coordinate based on screen pixels. Printer pixels are likely much smaller than screen pixels (think 600 DPI versus 72 DPI). If, as likely the case here, you assume a screen pixel is the same as a device pixel then the output will be very small on the page. To get what you were expecting, a widget image scaled to fit inside the margin, you need to do the scaling.

    Qt Code:
    1. #!env python
    2. import sys
    3. from PyQt5.QtGui import QPainter
    4. from PyQt5.QtPrintSupport import QPrinter
    5. from PyQt5.QtGui import QFont
    6. from PyQt5.QtWidgets import (QLabel, QApplication)
    7.  
    8. app = QApplication(sys.argv)
    9.  
    10. font = QFont('Times', 24)
    11. widget = QLabel('Lorem ipsum dolor sit amet, consectetur adipiscing elit')
    12. widget.setFont(font)
    13. widget.resize(256, 256)
    14. widget.setWordWrap(True)
    15.  
    16. # Print options
    17. printer = QPrinter(QPrinter.HighResolution)
    18. printer.setOrientation(QPrinter.Portrait)
    19. printer.setPaperSize(QPrinter.A4)
    20. printer.setPageSize(QPrinter.A4)
    21. printer.setPageMargins(15, 15, 15, 15, QPrinter.Millimeter)
    22. # Setting the margins and then calling setFullPage() will discard the margins.
    23. #printer.setFullPage(True)
    24. printer.setOutputFormat(QPrinter.PdfFormat)
    25. printer.setOutputFileName("testfile.pdf")
    26.  
    27. # Render/Paint it
    28. painter = QPainter()
    29. painter.begin(printer)
    30.  
    31. # Establish scaling transform
    32. scaleX = printer.pageRect().width() / widget.rect().width()
    33. scaleY = printer.pageRect().height() / widget.rect().height()
    34. useScale = min(scaleX, scaleY)
    35. painter.scale(useScale, useScale)
    36.  
    37. widget.render(painter)
    38. painter.end()
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Aug 2017
    Posts
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: PyQt5 QPrinting setFullpage doesn't works

    Oh, I see, I though that setFullpage would scale the contents automatically. Lesson learned.
    Thank you, ChrisW67, that pretty much fixes my issue. The printing of my widget is now a full page after scaling it.

    However, now I'm stuck on the very next step (not sure if I should make a new thread for it).
    The result is a PDF printed with just an image and no selectable text. MyWidget is suppose to mimic a MSAccess report for invoices, with its Logos, text, tables and stuff, so just an screenshot with the data won't do the job, it needs to be selected.
    Researching this issue, I've been reading about printing to pdf as a QTextDocument with html formatting, but that sounds like a very undesirable workaround for something like this. I also found something about QGraphicsScene but I don't think that's the best solution either.

    Is there any simple way to print a QWidget (with some QlineEdits and QLabels inside) as a PDF that can read text and not just an screenshotted version of MyWidget?

    Edit: For easier understanding, I need this (which is already a working Qwidget) in PDF:
    9T-KH7KlSkmsBUKW7xcbWA.jpg
    Last edited by Saelyth; 12th August 2017 at 12:54.

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: PyQt5 QPrinting setFullpage doesn't works

    I have previously had to generate a lot of forms of this nature. There is no dead easy way, and I ended either:
    • Painting the form entirely using the QPainter primitives. I draw as if the page was A4 sized with 0.1 point grid (ugly units I know) and used transforms to fit it to the actual page (A4, A5, US Letter, whatever) when printed.
    • Painting the fixed elements of the form from an SVG file and using the QPainter to fill in the variable information. I queried the SVG to find the boxes to contain text (by XML id) so that if I adjusted the SVG template the output would follow. You have a bit of fun with the SVG/painter/Device coordinates, but worked quite well for long tabular lists.
    • Sometimes use QTextDocument for simpler layouts. For more narrative text output a QTextDoument would be a good option.

    Either way there is quite a bit of work.

    There were some third-party (OS and paid) tools that I vaguely recall; CuteReport, NCReport, KD Reports. Never used them.

Similar Threads

  1. Replies: 3
    Last Post: 26th August 2016, 16:40
  2. Works on 64bit doesn't on 32 bit
    By daniel_dm in forum Newbie
    Replies: 3
    Last Post: 5th August 2013, 14:24
  3. Replies: 3
    Last Post: 6th July 2011, 07:59
  4. Replies: 1
    Last Post: 31st December 2010, 17:35
  5. QPrinter setFullPage(): Win/Linux Diffs
    By ChrisW67 in forum Qt Programming
    Replies: 2
    Last Post: 9th October 2009, 06:31

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.