QWebEngineView - yScroll Position setzen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nobuddy
User
Beiträge: 1022
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,

ich bin dabei PDF Dateien auszulesen und mittels Suche, Resultate ausgeben zu lassen.
Hierzu habe ich dann einen y-Wert zum jeweiligen match.
Nun versuche ich verzweifelt, auf den y-Wert zu scrollen, leider finde ich keinen Zugang um dies steuern zu können.

Hier mal den Code, den ich zu QWebEngineView nutze:

Code: Alles auswählen

import os
import sys
from pathlib import Path
from PyQt5.QtCore import (
    Qt,
    QUrl
)
from PyQt5.QtGui import (
    QDesktopServices
)
from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QWidget
)
from PyQt5.QtWebEngineWidgets import (
    QWebEngineSettings,
    QWebEngineView
)

class Browser(QWebEngineView):
    _windows = set()
    
    @classmethod
        def _removeWindow(cls, window):
            cls._windows.discard(window)

    @classmethod
    def newWindow(cls):
        window = cls()
        cls._windows.add(window)
        return window

    def __init__(self, parent=None):
        super().__init__(parent)
        # create image with QWebEngineView
        self.settings().setAttribute(
        QWebEngineSettings.PluginsEnabled, True
        )
        self.settings().setAttribute(
            QWebEngineSettings.PdfViewerEnabled, True
        )
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.page().geometryChangeRequested.connect(
            self.handleGeometryChange
        )
        #self.page().titleChanged.connect(self.setWindowTitle)

    def closeEvent(self, event):
        self._removeWindow(self)
        event.accept()

    def handleGeometryChange(self, rect):
        window = QWindow.fromWinId(self.winId())
        if window is not None:
            rect = rect.marginsRemoved(window.frameMargins())
        self.resize(rect.size())
        self.setFocus()
        self.show()

    def createWindow(self, mode):
        window = self.newWindow()
        if mode != QWebEnginePage.WebDialog:
            window.resize(800, 600)
            window.show()
            return window


path = '/home/path_to_pdf/mypdf.pdf'
if __name__ == '__main__':

    app = QApplication(sys.argv)
    browser = Browser()
    browser.setUrl(QUrl.fromLocalFile(path))
    browser.setGeometry(100, 100, 1200, 800)
    browser.show()
    sys.exit(app.exec_())
Welche Möglichkeit bietet sich hier an, um ein PDF-Dokument scrollbar per Code zu machen?

Grüße Nobuddy
Nobuddy
User
Beiträge: 1022
Registriert: Montag 30. Januar 2012, 16:38

Habe zur Veranschaulichung hier ein Beispiel.
Habe auch was ich beim Googeln häufig gestoßen bin "runJavaScript" eingebaut. Leider habe ich keine Ahnung, wie das zu handeln ist.
Hoffe, dass einer von Euch Profis, mir da weiterhelfen kann.

Code: Alles auswählen

class WindowBrowser(QMainWindow):
    def __init__(self, path=None):
        super().__init__()
        widget = QWidget()
        layout = QVBoxLayout(self)
        self.view = QWebEngineView()
        layout.addWidget(self.view)
        self.inputField = QLineEdit(self)
        self.inputField.setText('0')
        self.inputField.textChanged.connect(self.inputCallback)
        layout.addWidget(self.inputField)
        scrollButton = QPushButton(self)
        scrollButton.setText('yScroll')
        scrollButton.clicked.connect(self.yScroll)
        layout.addWidget(scrollButton)
        widget.setLayout(layout)
        if path:
            self.setCentralWidget(widget)
            self.view.load(QUrl.fromLocalFile(path))
        # We need to wait for the page to load before getting the position
        self.view.loadFinished.connect(self.on_load_finished)

    def inputCallback(self, text):
        try:
            int(text)
        except ValueError:
            self.inputField.setText('0')

    def yScroll(self):
        # scroll document to y-position
        try:
            y = int(self.inputField.text())
        except ValueError:
            y = 0
        # bad scrolling
        #self.view.scroll(0, y)
        #self.get_scroll_y(y)

    def on_load_finished(self, ok):
        if ok:
            # Use JavaScript to get the scroll position
            # This is more reliable than scrollPosition()
            self.view.page().runJavaScript(
                "document.scrollingElement.scrollTop",
                self.get_scroll_y
            )

    def get_scroll_y(self, y_pos):
        # The result from JavaScript is returned here
        print(f"Current scroll position (Y): {y_pos}")
        
path = '/home/path/to/myPDF.pdf'
if __name__ == '__main__':

    app = QApplication(sys.argv)
    win = WindowBrowser(path=path)
    win.show()
    sys.exit(app.exec_())
Nobuddy
User
Beiträge: 1022
Registriert: Montag 30. Januar 2012, 16:38

Nach langem Verweilen auf der QWebEngineView Seite von Qt, habe ich eine Möglichkeit gefunden das PDF im Viewer zu durch. Ergebnisse werden markiert und der Viewer springt automatisch zum ersten Resultat.
Wenn ich jetzt noch eine Ausgabe erstellen könnte, wo Seite und Position der Resultate ausgegeben wird, wäre das eine feine Sache.

Hier mein update:

Code: Alles auswählen

class WindowBrowser(QMainWindow):
    def __init__(self, path=None):
        super().__init__()
        widget = QWidget()
        layoutVertical = QVBoxLayout(self)
        layoutHorizontal = QHBoxLayout(self)
        self.view = Browser()
        layoutVertical.addWidget(self.view)
        self.searchField = QLineEdit(self)
        self.searchField.setText('0')
        self.searchField.textChanged.connect(self.inputCallback)
        layoutVertical.addWidget(self.searchField)
        self.searchButton = QPushButton(self)
        self.searchButton.setText('search')
        self.searchButton.clicked.connect(self.search)
        self.searchButton.setEnabled(False)
        layoutHorizontal.addWidget(self.searchButton)
        self.backButton = QPushButton(self)
        self.backButton.setText('back')
        self.backButton.clicked.connect(self.back)
        #self.backButton.setEnabled(False)
        layoutHorizontal.addWidget(self.backButton)
        self.forwardButton = QPushButton(self)
        self.forwardButton.setText('forward')
        self.forwardButton.clicked.connect(self.forward)
        #self.forwardButton.setEnabled(False)
        layoutHorizontal.addWidget(self.forwardButton)
        layoutVertical.addLayout(layoutHorizontal)
        widget.setLayout(layoutVertical)
        if path:
            self.setCentralWidget(widget)
            self.view.load(QUrl.fromLocalFile(path))

    def inputCallback(self, text):
        searchText = self.searchField.text()
        if searchText == '' and self.searchButton.isEnabled():
            self.searchButton.setEnabled(False)
        elif searchText != '' and not self.searchButton.isEnabled():
            self.searchButton.setEnabled(True)

    def search(self):
        # find text in pdf and scroll document to y-position
        self.view.page().findText(self.searchField.text())

    def back(self):
        self.view.page().triggerAction(QWebEnginePage.Back)

    def forward(self):
        self.view.page().triggerAction(QWebEnginePage.Forward)
Die Funktionen back und forward funktionieren leider nicht.
Vielleicht kann mir jemand sagen, es es richtig angewendet wird?
Antworten