如何在使用 QWebEngineView 'loadFinished' 加载页面后立即更改 html 元素?

How to change html elements immediately after loading page with QWebEngineView 'loadFinished'?

我想在 html 页面加载时使用 QWebEngineView 做更多的事情,而不是手动发送信号来更改 html.I 手动使用按钮发送信号三次,与初始加载一次共计四次:


>>

将自定义信号发送到 js...
将自定义信号发送到 js...
将自定义信号发送到 js...
将自定义信号发送到 js...

run.py

import os
from time import time
from PyQt5.QtCore import QUrl, pyqtSignal
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton


class WebEngineView(QWebEngineView):
    customSignal = pyqtSignal(str)

    def __init__(self, *args, **kwargs):
        super(WebEngineView, self).__init__(*args, **kwargs)
        self.channel = QWebChannel(self)
        self.channel.registerObject('Bridge', self)
        self.page().setWebChannel(self.channel)

    def sendCustomSignal(self):
        print("sendCustomSignal to js...")
        self.customSignal.emit('current time:' + str(time()))


class Window(QWidget):
    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        layout = QVBoxLayout(self)
        self.webview = WebEngineView(self)
        layout.addWidget(self.webview)
        layout.addWidget(QPushButton('Send', self, clicked=self.webview.sendCustomSignal))
        self.webview.load(QUrl.fromLocalFile(os.path.abspath('show.html')))
        self.webview.loadFinished.connect(self.webview.sendCustomSignal)


if __name__ == "__main__":
    from PyQt5.QtWidgets import QApplication
    import sys
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())

show.html

<!DOCTYPE html>
<html lang="en">
    <p id="log"></p>
    <script src="qwebchannel.js"></script>
    <script>
            new QWebChannel(qt.webChannelTransport,
                function(channel) {
                    window.Bridge = channel.objects.Bridge;
                    Bridge.customSignal.connect(function(text) {
                       showLog("Signal received:" + text);
                    });
                }
            );
            function showLog(text) {
                var ele = document.getElementById("result");
                ele.value = ele.value + text + "\n";
            }
        </script>
    <h1>Hello PyQt!</h1>
    <textarea id="result" rows="20" cols="100"></textarea>
</html>

发出信号发出loadFinished信号并不意味着所有脚本都已执行,在这种情况下,导出的对象最好调用一个槽来指示已经建立连接。

import os
from time import time
from PyQt5.QtCore import QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton


class WebEngineView(QWebEngineView):
    customSignal = pyqtSignal(str)

    def __init__(self, *args, **kwargs):
        super(WebEngineView, self).__init__(*args, **kwargs)
        self.channel = QWebChannel(self)
        self.channel.registerObject("Bridge", self)
        self.page().setWebChannel(self.channel)

    def sendCustomSignal(self):
        print("sendCustomSignal to js...")
        self.customSignal.emit("current time:" + str(time()))

    @pyqtSlot()
    def init(self):
        self.sendCustomSignal()


class Window(QWidget):
    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        layout = QVBoxLayout(self)
        self.webview = WebEngineView(self)
        layout.addWidget(self.webview)
        layout.addWidget(
            QPushButton("Send", self, clicked=self.webview.sendCustomSignal)
        )
        self.webview.load(QUrl.fromLocalFile(os.path.abspath("show.html")))


if __name__ == "__main__":
    from PyQt5.QtWidgets import QApplication
    import sys

    sys.argv.append("--remote-debugging-port=8000")
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())
<!DOCTYPE html>
<html lang="en">
    <p id="log"></p>
    <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
    <script>
        window.onload = function(){
            new QWebChannel(qt.webChannelTransport,
                function(channel) {
                    window.Bridge = channel.objects.Bridge;
                    Bridge.customSignal.connect(function(text) {
                       showLog("Signal received:" + text);
                    });
                    Bridge.init();
                }
            );
            function showLog(text) {
                var ele = document.getElementById("result");
                ele.value = ele.value + text + "\n";
            }
        }
        </script>
    <h1>Hello PyQt!</h1>
    <textarea id="result" rows="20" cols="100"></textarea>
</html>