2

I am developing an app using PyQt4. And I would like to have an option to print the main widget to a pdf document. I have a custom qlayout for the main widget and I want to create a pdf document with that qlayout. I read a lot about pyqt qprinter, but I'm not sure that's what I want.

Could anyone suggest how I could create a pdf with a qlayout full of qwidgets?

1 Answer 1

3

Use QPixmap.grabWidget to render the widget to a pixmap, then paint that on a QPrinter which can then convert it to a pdf:

import sys
from PyQt4 import QtCore, QtGui

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.text = QtGui.QTextEdit(self)
        self.text.setText(open(__file__).read())
        self.edit = QtGui.QLineEdit(self)
        self.edit.setText('/tmp/test.pdf')
        self.buttonSave = QtGui.QPushButton('Save', self)
        self.buttonSave.clicked.connect(self.handleSave)
        layout = QtGui.QGridLayout(self)
        layout.addWidget(self.text, 0, 0, 1, 2)
        layout.addWidget(self.edit, 1, 0, 1, 1)
        layout.addWidget(self.buttonSave, 1, 1, 1, 1)

    def handleSave(self):
        printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
        printer.setPageSize(QtGui.QPrinter.A6)
        printer.setColorMode(QtGui.QPrinter.Color)
        printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
        printer.setOutputFileName(self.edit.text())
        pixmap = QtGui.QPixmap.grabWidget(self).scaled(
            printer.pageRect(QtGui.QPrinter.DevicePixel).size().toSize(),
            QtCore.Qt.KeepAspectRatio)
        painter = QtGui.QPainter(printer)
        painter.drawPixmap(0, 0, pixmap)
        painter.end()

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(600, 100, 640, 640)
    window.show()
    sys.exit(app.exec_())

EDIT:

If the QPainter part won't work for some reason on your setup, you could try the alternative save method below:

    def handleSave(self):
        printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
        printer.setPageSize(QtGui.QPrinter.A9)
        printer.setColorMode(QtGui.QPrinter.Color)
        printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
        printer.setOutputFileName(self.edit.text())
        self.render(printer)

Or another alternative would be to use a QTextDocument:

    def handleSave(self):
        printer = QtGui.QPrinter()
        printer.setPageSize(QtGui.QPrinter.A5)
        printer.setResolution(200)
        printer.setColorMode(QtGui.QPrinter.Color)
        printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
        printer.setOutputFileName(self.edit.text())
        size = printer.pageRect(QtGui.QPrinter.DevicePixel).size()
        pixmap = QtGui.QPixmap.grabWidget(self).scaled(
            size.toSize(), QtCore.Qt.KeepAspectRatio,
            QtCore.Qt.SmoothTransformation)
        data = QtCore.QByteArray()
        buffer = QtCore.QBuffer(data)
        pixmap.save(buffer, 'PNG')
        document = QtGui.QTextDocument()
        document.setPageSize(size)
        document.setHtml('<img src="data:image/png;base64,%s"/>' %
                         bytes(data.toBase64()).decode('ascii'))
        document.print_(printer)
Sign up to request clarification or add additional context in comments.

10 Comments

When I run you're code it gives me two errors: QPainter::end: Painter not active, aborted and QPainter::begin(): Returned false do you know how to fix that?
And when do I write the qlayout to the pdf?
@CheynShmuel. The code works perfectly for me. Did you edit it in some way? It makes no sense to print a layout because it is not visible. You have to print the widget that the layout is set on.
No, I copy-pasted your code, and the GUI shows up as expected, but the save button doesn't work.
@CheynShmuel. What platform are you on? What versions of PyQt4 and Qt4 are you using?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.