Python Forum

Full Version: [solved] How to display a pdf-file in a PyQt6 widget
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hello,

The problem
I would like to display a pdf-file in a widget. That widget is part of a layout. Since the pdf files can contain more than one page, it would be great if I can also turn pages. I have searched for days in the internet, always running into new issues (e.g. works only with PyQt5, etc.)

The question
Is there a straight-forward solution (module, package) known to work with PyQt6. I do not need fancy stuff. The simpler the better.

Thanks again for all hints & tips!
(Mar-25-2022, 03:26 AM)Larz60+ Wrote: [ -> ]see: https://www.kdab.com/browse-pdfs-in-a-qt...plication/

I highly appreciate your reply. The "kdab"-Link is already known to me ... and I failed to use it in the past:

Reason:
- I (believe to) know how to install additional packages in Python. In the past I used pip, and recently I started to use Pycharm, and I am using now Pycham's functionality to install packages).
- It seems the "kdab"-Example is in C .... so it doesn't mention a Python package at all. I searched in Pycharm and in the Internet, but it seems there is no Python Package for that.

==> So, I guess I would have to download a QtPDF-source-code from github, compile it as mentioned in the link ... but I am sure, the next problem would be, how to import what I have compiled into my Python program. Will I be able to use "import <package_name> .... ?

I know, that is quite a beginner issue ... but somewhere I have to start ...
BigMan Wrote:(believe to) know how to install additional packages in Python. In the past I used pip, and recently I started to use Pycharm, and I am using now Pycham's functionality to install packages)
Just an FYI:
PyCharm Wrote:By default, PyCharm uses pip to manage project packages. For Conda environments you can use the conda package manager. In PyCharm, you can preview and manage packages in the Python Packages tool window and in the Python interpreter Settings/Preferences.
This is how I show PDF in PyQt5, external modules are not required.

from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineView
from os import path

class MainWindow(QMainWindow):
    def __init__(self):
        super(QMainWindow, self).__init__()

        self.setWindowTitle("PDF Viewer")
        self.setGeometry(0, 28, 1000, 750)

        self.webView = QWebEngineView()
        self.webView.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
        self.webView.settings().setAttribute(QWebEngineSettings.PdfViewerEnabled, True)
        self.setCentralWidget(self.webView)

    def url_changed(self):
        self.setWindowTitle(self.webView.title())

    def go_back(self):
        self.webView.back()

if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    if len(sys.argv) > 1:
        win.webView.setUrl(QUrl(f"file://{sys.argv[1]}"))
    else:
        wd = path.dirname(sys.argv[0])
        test_pdf = "test.pdf"
        win.webView.setUrl(QUrl(f"file://{wd}/{test_pdf}"))
    sys.exit(app.exec_())
With some changes it works in PyQt6

from PyQt6.QtCore import QUrl
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView #, QWebEngineSettings
from os import path

class MainWindow(QMainWindow):
    def __init__(self):
        super(QMainWindow, self).__init__()

        self.setWindowTitle("PDF Viewer")
        self.setGeometry(0, 28, 1000, 750)

        self.webView = QWebEngineView()
        self.webView.settings().setAttribute(self.webView.settings().WebAttribute.PluginsEnabled, True)
        self.webView.settings().setAttribute(self.webView.settings().WebAttribute.PdfViewerEnabled, True)
        self.setCentralWidget(self.webView)

    def url_changed(self):
        self.setWindowTitle(self.webView.title())

    def go_back(self):
        self.webView.back()

if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    if len(sys.argv) > 1:
        win.webView.setUrl(QUrl(f"file://{sys.argv[1]}"))
    else:
        wd = path.dirname(sys.argv[0])
        test_pdf = "test.pdf"
        win.webView.setUrl(QUrl(f"file://{wd}/{test_pdf}"))
    sys.exit(app.exec())
(Mar-25-2022, 11:54 AM)Larz60+ Wrote: [ -> ]Just an FYI:
PyCharm Wrote:By default, PyCharm uses pip to manage project packages. For Conda environments you can use the conda package manager. In PyCharm, you can preview and manage packages in the Python Packages tool window and in the Python interpreter Settings/Preferences.

Thanks - really!
My issue is that the code/module/packages needed to do the solution as described in https://www.kdab.com/browse-pdfs-in-a-qt...plication/ are not listed in the Package-Managertool from PyCham. Instead code has to be downloaded via git and compiled. This has for me two issues:
- git submodule .... tries to download from https://pdfium.googlesource.com/pdfium/' ... which constantly fails. I assume this is due to the Great China Firewalll, which blocks google (I am sitting currently Shanghai).
- while the above download problem is real, I assume the next issue would be that the link's example is a C code ... I have now idea, how I can later "import" then what I would have compiled into my Python program. <- well, maybe there is a way I would find by try-and-error, but as long as issue #1 isn't solve not worth to think about it ...

Supplement: The problem is solved. The suggestion from Axel with the QWebEngineView works great!!!
@Axel from Erfurt: Thanks a lot for the code! I read many times before about the option to do it with the QWebEngineView ... put it always looked so complicated and scared me (I also believe, the examples I had where based on PyQt5, etc. etc.) But now it works. Great. Thanks a million times again!
(Mar-25-2022, 05:32 PM)Axel_Erfurt Wrote: [ -> ]With some changes it works in PyQt6

from PyQt6.QtCore import QUrl
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView #, QWebEngineSettings
from os import path

class MainWindow(QMainWindow):
    def __init__(self):
        super(QMainWindow, self).__init__()

        self.setWindowTitle("PDF Viewer")
        self.setGeometry(0, 28, 1000, 750)

        self.webView = QWebEngineView()
        self.webView.settings().setAttribute(self.webView.settings().WebAttribute.PluginsEnabled, True)
        self.webView.settings().setAttribute(self.webView.settings().WebAttribute.PdfViewerEnabled, True)
        self.setCentralWidget(self.webView)

    def url_changed(self):
        self.setWindowTitle(self.webView.title())

    def go_back(self):
        self.webView.back()

if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    if len(sys.argv) > 1:
        win.webView.setUrl(QUrl(f"file://{sys.argv[1]}"))
    else:
        wd = path.dirname(sys.argv[0])
        test_pdf = "test.pdf"
        win.webView.setUrl(QUrl(f"file://{wd}/{test_pdf}"))
    sys.exit(app.exec())

I copied and paste your code while making sure to have a "test.pdf" file in my working directory. Do note that I hard coded the file path on the "else" statement just to make sure that it points correctly. I was able to view a png or a jpg file. However, once I change it to view a pdf file it crashed without any error on the terminal. It just outright closes the window. Any idea what happened?
wd = path.dirname(sys.argv[0])

should be

wd = path.dirname(path.abspath(sys.argv[0]))

from PyQt6.QtCore import QUrl
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView #, QWebEngineSettings
from os import path
 
class MainWindow(QMainWindow):
    def __init__(self):
        super(QMainWindow, self).__init__()
 
        self.setWindowTitle("PDF Viewer")
        self.setGeometry(0, 28, 1000, 750)
 
        self.webView = QWebEngineView()
        self.webView.settings().setAttribute(self.webView.settings().WebAttribute.PluginsEnabled, True)
        self.webView.settings().setAttribute(self.webView.settings().WebAttribute.PdfViewerEnabled, True)
        self.setCentralWidget(self.webView)
 
    def url_changed(self):
        self.setWindowTitle(self.webView.title())
 
    def go_back(self):
        self.webView.back()
 
if __name__ == '__main__':
 
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    if len(sys.argv) > 1:
        win.webView.setUrl(QUrl(f"file://{sys.argv[1]}"))
    else:
        wd = path.dirname(path.abspath(sys.argv[0]))
        print(f"wd: {wd}")
        test_pdf = "test.pdf"
        win.webView.setUrl(QUrl(f"file://{wd}/{test_pdf}"))
    sys.exit(app.exec())
Pages: 1 2