【问题标题】:cannot change backgroundImage using QWebEnginePage::runJavaScript()无法使用 QWebEnginePage::runJavaScript() 更改 backgroundImage
【发布时间】:2019-10-31 18:39:05
【问题描述】:

我本来想解决 this problem 的问题,但是当我测试了 QWebEnginePage::runJavaScript() 的行为后,我发现我什至无法通过以下代码使用 QWebEnginePage::runJavaScript() 更改 backgroundImage,那为什么呢?

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_())

【问题讨论】:

    标签: python pyqt pyqt5 qtwebengine qwebengineview


    【解决方案1】:

    您要修改 DOM,因此必须已经创建了它,在您的情况下,您在加载页面之前使用 runJavaScript 并且未构建 DOM。考虑到有两种可能的解决方案:

    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_())
    
    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_())
    

    【讨论】:

    • 谢谢!有用 !我尝试使用 QWebEnginePage::runJavaScript() 以几乎相同的代码逻辑将网页进度条注入网页,但失败了,您能帮忙forum.qt.io/topic/103975/… 吗?谢谢!
    • @iMath 我不知道该代码的作用,我需要更多时间来分析它,但如果它与您之前的问题相同,它将无法工作。您上一个问题的问题是您应该将脚本直接加载到 DOM 的创建中以测量进度,但是在我当前的响应中,是在我完成加载 DOM 的过程时测量的,所以没有什么可测量的,为什么失败。
    • 我已按照您的回答并更改了我的代码以在上一个问题中设置 webEngineScript.setInjectionPoint(QWebEngineScript.DocumentReady) 相关内容,我想当前的问题是关于 JavaScript 和 QWebEngineScript。我因为对 JS 不太了解而被困在这里。
    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    相关资源
    最近更新 更多