не может изменить backgroundImage, используя QWebEnginePage :: runJavaScript () - PullRequest
2 голосов
/ 18 июня 2019

Изначально я хочу решить эту проблему , но, поскольку я протестировал поведение QWebEnginePage :: runJavaScript () , я обнаружил, что не могу даже изменить backgroundImage с помощью QWebEnginePage :: runJavaScript () со следующим кодом, так почему?

import sys

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWebEngineCore import *


class WebEngineView(QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.webPage = self.page()
        # self.webPage = WebEnginePage()
        self.webPage.load(QUrl('https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style'))
        self.webPage.runJavaScript('''
                                window.addEventListener("load", function(event) {
                                        alert(document.title);
                                        document.body.style.backgroundImage = "url('https://www.w3schools.com/jsref/img_tree.png')";

                                });
                     ''')  # QWebEngineScript.MainWorld


if __name__ == "__main__":

    app = QApplication(sys.argv)
    app.setAttribute(Qt.AA_UseSoftwareOpenGL)
    webEngineView = WebEngineView()
    webEngineView.show()
    sys.exit(app.exec_())

1 Ответ

2 голосов
/ 18 июня 2019

Вы хотите изменить DOM, чтобы он уже был создан, в вашем случае вы используете runJavaScript до загрузки страницы, а DOM не создается. Учитывая, что есть 2 возможных решения:

  • Используйте сигнал loadFinished для выполнения скрипта после загрузки страницы:
import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets


class WebEngineView(QtWebEngineWidgets.QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.loadFinished.connect(self.on_load_finished)

        self.load(
            QtCore.QUrl(
                "https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style"
            )
        )

    @QtCore.pyqtSlot(bool)
    def on_load_finished(self, ok):
        if ok:
            script = """
            alert(document.title);
            document.body.style.backgroundImage = "url('https://www.w3schools.com/jsref/img_tree.png')";
            """
            self.page().runJavaScript(script)


if __name__ == "__main__":
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_UseSoftwareOpenGL)
    app = QtWidgets.QApplication(sys.argv)
    w = WebEngineView()
    w.show()
    sys.exit(app.exec_())
  • Используйте QWebEngineScript для реализации user script, которая позволяет вводить код JavaScript:
import sys

from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets


class WebEngineView(QtWebEngineWidgets.QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)

        script = QtWebEngineWidgets.QWebEngineScript()
        name = "test"
        source = """
        alert(document.title);
        document.body.style.backgroundImage = "url('https://www.w3schools.com/jsref/img_tree.png')";
        """
        script.setName(name)
        script.setSourceCode(source)
        script.setInjectionPoint(
            QtWebEngineWidgets.QWebEngineScript.DocumentReady
        )
        script.setRunsOnSubFrames(True)
        script.setWorldId(QtWebEngineWidgets.QWebEngineScript.ApplicationWorld)
        self.page().scripts().insert(script)

        self.load(
            QtCore.QUrl(
                "https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style"
            )
        )


if __name__ == "__main__":
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_UseSoftwareOpenGL)
    app = QtWidgets.QApplication(sys.argv)
    w = WebEngineView()
    w.show()
    sys.exit(app.exec_())
...