如何在使用 QWebEngineView 'loadFinished' 加载页面后立即更改 html 元素?
Posted
技术标签:
【中文标题】如何在使用 QWebEngineView \'loadFinished\' 加载页面后立即更改 html 元素?【英文标题】:How to change html elements immediately after loading page with QWebEngineView 'loadFinished'?如何在使用 QWebEngineView 'loadFinished' 加载页面后立即更改 html 元素? 【发布时间】:2020-10-15 13:00:00 【问题描述】:我想在html页面加载时使用QWebEngineView做更多的事情,而不是手动发送信号改变html。我手动使用按钮发送信号3次,初始加载一次,总共四次次:
>>
向 js 发送自定义信号... 将自定义信号发送到 js... 将自定义信号发送到 js... 将自定义信号发送到 js...
运行.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>
【问题讨论】:
1) 更好地解释你自己,因为你的问题不清楚,2) 你为什么使用 time.sleep? @eyllanesc 嗨!我修改了我的描述和代码,希望你能理解并帮助我,在此先感谢 【参考方案1】:发出信号并发出 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>
【讨论】:
太好了!感谢您的回答,这对扩展我的功能很有帮助!以上是关于如何在使用 QWebEngineView 'loadFinished' 加载页面后立即更改 html 元素?的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用 QWebEngineView 'loadFinished' 加载页面后立即更改 html 元素?
如何使用 QWebEngineView 和 qtwebchannel.js 逐步加载 javascript?
如何在 QWebEngineView 中设置背景图像 [重复]