我目前正在寻找一种使用 PyQt5 的QWebEngineView使用 Python 和 HTML/CSS/JS 创建 GUI 桌面应用程序的方法。
在我的小演示应用程序中,我使用QWebChannel发布 Python QObject到 JavaScript 端,以便数据可以共享和来回传递。到目前为止,共享和连接插槽和信号工作正常。
我在同步简单(属性)值时遇到了困难。从我读过的内容来看,要走的路是通过装饰的 getter 和 setter 函数在共享 QObject 中实现一个 pyqtProperty,并在 setter 中发出一个额外的信号,用于在值发生变化时通知 JavaScript。下面的代码显示了这一点,到目前为止它工作正常:
import sys
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
class HelloWorldHtmlApp(QWebEngineView):
html = '''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script>
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
});
</script> …Run Code Online (Sandbox Code Playgroud) 在PySide信号和插槽页面上,它说:"信号是实例拥有的运行时对象,它们不是类属性".显然,QObject构造函数在Signals的类属性中查找并将它们复制到对象实例.我的测试程序证实了这一点.
来自PySide导入QtCore
class Klass(QtCore.QObject):
lst = []
sig = QtCore.Signal(str)
def main():
obj1 = Klass()
obj2 = Klass()
print "id: obj1.lst = {}, obj1.sig = {}".format(id(obj1.lst), id(obj1.sig))
print "id: obj2.lst = {}, obj2.sig = {}".format(id(obj2.lst), id(obj2.sig))
print "id: klass.lst = {}, klass.sig = {}".format(id(Klass.lst), id(Klass.sig))
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
在我的输出中,您可以看到现在有三个信号对象,而lst-member的id对于对象和类都是相同的.
id: obj1.lst = 4317739344, obj1.sig = 4297560376
id: obj2.lst = 4317739344, obj2.sig = 4297560400
id: klass.lst = 4317739344, klass.sig = 4317851072
Run Code Online (Sandbox Code Playgroud)
隐式创建对象属性只是令人困惑,因此风格很差(恕我直言).也许他们确实有充分的理由,但我没有看到他们.所以我的问题是:为什么他们选择这个解决方案而不是仅仅在构造函数中创建信号作为常规属性?