繁体   English   中英

使用 QWebEngineView 以编程方式更改 PDF.js 中的页面

[英]Programmatically change page in PDF.js with QWebEngineView

我正在 PyQt5 中制作一个应用程序,其中涉及使用 Mozilla 的QWebEngineViewPDF.js显示 PDF。

我能够显示 PDF 没有问题,但我不知道如何:

  • 1:设置页面加载,或
  • 2:页面已经加载后更新

我已经尝试了其他 Stackoverflow 帖子中涉及使用self.runJavaScript()来更改它的众多选项,但它总是导致“无法设置未定义的属性”或“对象为 NoneType”。

这是我的方法:

def load_file(self, file, page=0) -> None:
        url = QtCore.QUrl().fromLocalFile(os.path.abspath("./pdfjs/web/viewer.html"))
        query = QtCore.QUrlQuery()
        query.addQueryItem("file", os.path.normpath(os.path.abspath(file)))
        url.setQuery(query)
        self.pdf_view.load(url)

其中self.pdf_view是 QWebEngineView。

对于如何实现这一点,我将不胜感激。

编辑:我能够用#符号指定加载页面,但至于在不重新加载整个内容的情况下更改页面,我仍然不知道。

PDF.js查看器加载一些脚本,这些脚本创建一个PDFViewer对象,该对象具有以编程方式导航页面所需的所有属性。 因此,您只需在主查看器页面上运行一些简单的 javascript 即可获得所需的功能。 为了让事情变得更好用,提供一种同步运行 javascript 的方法也很有帮助,这样可以更轻松地访问返回值。

下面是一个实现该功能的简单工作演示(仅在 Linux 上测试)。 希望应该清楚如何使其适应您自己的应用程序:

import sys, os
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets

# PDFJS = '/usr/share/pdf.js/web/viewer.html'
PDFJS = './pdfjs/web/viewer.html'

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.buttonNext = QtWidgets.QPushButton('Next Page')
        self.buttonNext.clicked.connect(lambda: self.changePage(+1))
        self.buttonPrev = QtWidgets.QPushButton('Previous Page')
        self.buttonPrev.clicked.connect(lambda: self.changePage(-1))
        self.viewer = QtWebEngineWidgets.QWebEngineView()
        layout = QtWidgets.QGridLayout(self)
        layout.addWidget(self.viewer, 0, 0, 1, 2)
        layout.addWidget(self.buttonPrev, 1, 0)
        layout.addWidget(self.buttonNext, 1, 1)

    def loadFile(self, file):
        url = QtCore.QUrl.fromLocalFile(os.path.abspath(PDFJS))
        query = QtCore.QUrlQuery()
        query.addQueryItem('file', os.path.abspath(file))
        url.setQuery(query)
        self.viewer.load(url)

    def execJavaScript(self, script):
        result = None
        def callback(data):
            nonlocal result
            result = data
            loop.quit()
        loop = QtCore.QEventLoop()
        QtCore.QTimer.singleShot(
            0, lambda: self.viewer.page().runJavaScript(script, callback))
        loop.exec()
        return result

    def changePage(self, delta):
        page = self.execJavaScript(
            'PDFViewerApplication.pdfViewer.currentPageNumber')
        self.setCurrentPage(page + int(delta))

    def setCurrentPage(self, page):
        count = self.execJavaScript(
            'PDFViewerApplication.pdfViewer.pagesCount')
        if 1 <= page <= count:
            self.execJavaScript(
                f'PDFViewerApplication.pdfViewer.currentPageNumber = {page}')

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    if len(sys.argv) > 1:
        window.loadFile(sys.argv[1])
    window.setGeometry(600, 50, 800, 600)
    window.show()
    sys.exit(app.exec_())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM