python - 如何在使用 QWebEngineView 'loadFinished' 加载页面后立即更改 html 元素?
问题描述
我想在html页面加载时使用QWebEngineView做更多的事情,而不是手动发送信号来改变html。我手动使用按钮发送信号3次,初始加载一次,总共4次:
>>
sendCustomSignal 到 js...
sendCustomSignal 到 js...
sendCustomSignal 到 js...
sendCustomSignal 到 js...
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_())
显示.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>
推荐阅读
- c# - 有没有办法获得操纵杆的按钮数量?
- mysql - 从实例文件中恢复 mysql 数据
- forms - 在创建之前或之后将对象保存到后端的最佳前端实践
- firebase - 以编程方式检查 Cloud Firestore 读/写计数
- python - Beautifulsoup4 没有为 pipenv 安装
- azure - 八达通中的输出变量 - 错误地传递空值
- r - RStudio:ggplot默认颜色变化
- flutter - DropdownButtonFormField 不是第一次重置
- azure-keyvault - 在 Azure Key Vault 上管理对凭据的细粒度访问
- java - JavaFX - 如何选择一种形状来制作动画?