python - QWebEnginePage 与 javascript 交互不起作用?
问题描述
我不熟悉javascript
和QWebEnginePage
。
当我设置self.content.setText('text')
内容时,QWebEngineView
内容没有改变?
蟒蛇代码
class Document(QObject):
textChanged = pyqtSignal(str)
def __init__(self):
super().__init__()
self.text = ''
def setText(self, text):
self.text = text
self.textChanged.emit(text)
print('emit')
class Demo(QWebEngineView):
def __init__(self):
super().__init__()
self.content = Document()
page = self.page()
channel = QWebChannel()
channel.registerObject('content', self.content)
page.setWebChannel(channel)
with open('index.html') as f:
self.setHtml(f.read())
self.content.setText('text')
app = QApplication([])
demo = Demo()
demo.resize(500, 400)
demo.show()
app.exec()
索引html:
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<head>
<script src="qwebchannel.js"></script>
</head>
<body>
<div id="placeholder">22</div>
<script>
'use strict';
var placeholder = document.getElementById('placeholder');
var updateText = function (text) {
placeholder.innerHTML = text;
console.log(text);
}
new QWebChannel(qt.webChannelTransport,
function (channel) {
var content = channel.objects.content;
updateText(content.text);
content.textChanged.connect(updateText);
}
);
</script>
</body>
</html>
解决方案
您有以下错误:
channel 是一个局部变量,一旦“Demo”构造函数完成就会被删除,它是 Python 和 Javascript 通信的中介。解决方案是通过将其传递给父级(Qt 样式)或使其成为类的属性来延长生命周期。
在 .html 您尝试包含 qwebchannel.js 但通常您应该使用
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
.如果您将 QObject 导出到 javascript,则只会导出 Q-Properties、QSlot 和 QSignals,因为 QWebChannel 使用 QMetaObject instropection,但“文本”不是它们,因此它在 javascript 中是未定义的。解决方案是将其公开为 pyqtProperty。
import os
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebChannel import QWebChannel
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class Document(QObject):
textChanged = pyqtSignal(str)
def __init__(self):
super().__init__()
self._text = ""
def text(self):
return self._text
def setText(self, text):
self._text = text
self.textChanged.emit(text)
print("emit")
text = pyqtProperty(str, fget=text, fset=setText, notify=textChanged)
class Demo(QWebEngineView):
def __init__(self):
super().__init__()
self.content = Document()
channel = QWebChannel(self)
channel.registerObject("content", self.content)
self.page().setWebChannel(channel)
filename = os.path.join(CURRENT_DIR, "index.html")
self.load(QUrl.fromLocalFile(filename))
self.content.setText("text")
def main():
app = QApplication([])
demo = Demo()
demo.resize(500, 400)
demo.show()
app.exec()
if __name__ == "__main__":
main()
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<head>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<div id="placeholder">22</div>
<script>
'use strict';
var placeholder = document.getElementById('placeholder');
var updateText = function (text) {
placeholder.innerHTML = text;
console.log(text);
}
new QWebChannel(qt.webChannelTransport,
function (channel) {
var content = channel.objects.content;
updateText(content.text);
content.textChanged.connect(updateText);
}
);
</script>
</body>
</html>
推荐阅读
- hadoop - Hive 仅获取值的最大出现次数
- reactjs - Google Cloud:react-i18next 未在 React 应用程序中加载 json 翻译文件
- django - Django 2 网址模式
- css - Bootstrap,scss,在scss代码中使用一些类名,而不是写在html文件中
- c# - 在 blazor 中添加动态组件列表
- node.js - 已安装 npm 但找不到命令
- node.js - 从 AWS Lambda 快速返回响应
- java - 无法正常工作时执行
- java - 打印文本文件的最小值和最大值并返回 null
- reactjs - FirebaseUI 与 create-react-app