Search code examples
pythonpdf-generationpyside6

Create a link with QPdfWriter


I'm writing a GUI application in Python using the PySide6 library, and I want to write PDFs. I usually use the reportlab library for writing PDFs, but I see that PySide6 has a QPdfWriter class. I'd like to avoid an extra dependency on reportlab if PySide6 is sufficient, but I can't see a way to create a link in the PDF, either to a section of the document or to a web site.

Is it possible to add a link to a PDF with QPdfWriter, or will it only support drawing and text?

Here's an example where I create a PDF with some text, and I'd like to turn the text into a link to the web page.

from PySide6.QtGui import QPdfWriter, QPainter, QPageSize
from PySide6.QtWidgets import QApplication

app = QApplication()
pdf = QPdfWriter('example.pdf')
pdf.setPageSize(QPageSize.Letter)
painter = QPainter(pdf)
painter.drawText(painter.window().width()//2,
                 painter.window().height()//2,
                 'https://donkirkby.github.io')
painter.end()

Solution

  • One possible solution is to use QTextDocument:

    from PySide6.QtGui import QGuiApplication, QPageSize, QPdfWriter, QTextDocument
    
    app = QGuiApplication()
    
    html = "<a href='https://donkirkby.github.io'>https://donkirkby.github.io</a>"
    
    
    pdf = QPdfWriter("example.pdf")
    pdf.setPageSize(QPageSize.Letter)
    
    document = QTextDocument()
    document.setHtml(html)
    document.print_(pdf)
    

    You can use QWebEnginePage, it is not yet available in Qt6 so PySide2 should be used for the example:

    from PySide2.QtWidgets import QApplication
    from PySide2.QtWebEngineWidgets import QWebEnginePage
    
    app = QApplication()
    
    html = """
    <!DOCTYPE html>
    <html>
      <head>
        <title>Title of the document</title>
        <style>
            .container {
                position: absolute;
                top: 50%;
                left: 50%;
                -moz-transform: translateX(-50%) translateY(-50%);
                -webkit-transform: translateX(-50%) translateY(-50%);
                transform: translateX(-50%) translateY(-50%);
            }
        </style>
      </head>
      <body>
        <div class="container">
            <a href='https://donkirkby.github.io'>https://donkirkby.github.io</a>
        </div>
      </body>
    </html>
    """
    
    page = QWebEnginePage()
    
    
    def handle_load_finished():
        page.printToPdf("example.pdf")
    
    
    def handle_pdf_printing_finished():
        app.quit()
    
    
    page.loadFinished.connect(handle_load_finished)
    page.pdfPrintingFinished.connect(handle_pdf_printing_finished)
    
    page.setHtml(html)
    
    
    app.exec_()