赞
踩
本文是使用Python创建WebUI(上篇)的姊妹篇,讲述如何在Python调用JavaScript===============================================================================================================================================================
一、原理
用一句话就能说明Python向JavaScript传递信息的原理:当QWebChannel引入一个QObject后,该Object的signal也会在JavaScript域出现。
二、代码实践
这次我们使用Qt自带的QTimer。QTimer可以有间隔的发送信号,这样可以在JavaScript中得到一个时钟。当然,这种用法没有实际意义,因为JavaScript已经自带了timeout机制。不过,读者朋友们可以举一反三,把QTimer替换为网络管理器、串口、蓝牙等Qt的底层机制,达到JavaScript操作底层硬件的目的。
还是利用我们上次的代码。首先在webui.py里增加两行:
class MainWin(QWebEngineView):
def __init__(self,main_entry):
QWebEngineView.__init__(self)
self.__channel = QWebChannel(self.page())
self.__my_object = MyObjectCls(self)
self.__tmr = QTimer() # NEW CODE
self.__channel.registerObject('MyObject',self.__my_object)
self.__channel.registerObject('MyTimer',self.__tmr) # NEW CODE
self.page().setWebChannel(self.__channel)
self.__my_object.sigSetParentWindowTitle.connect(self.setWindowTitle)
self.page().load(QUrl.fromLocalFile(main_entry))
这样就在QWebChannel里添加了一个MyTimer。
然后在index.html里加一个小标记
Counter
Console Output
下面修改control.js。Qt Signal可以直接接到一个JavaScript函数上。对于QTimer,其timeout是我们关心的Signal,因此就用my_timer.timeout.connect(function)的方法使用它。当PyQt一端发出信号的时候,相应的function就会被执行。
$(document).ready(function() {
new QWebChannel(qt.webChannelTransport, function(channel) {
var my_object = channel.objects.MyObject;
$("#btn0").click(function() {
my_object.consolePrint($("#txt0").val());
});
$("#btn1").click(function() {
my_object.setParentWindowTitle($("#txt1").val());
});
$("#btn2").click(function() {
my_object.saveFile($("#txt2").val(),$("#txt3").val());
});
NEW CODE var my_timer = channel.objects.MyTimer;
my_timer.timeout.connect(function() {
$("#ctr0").text(1 + parseInt($("#ctr0").text()));
});
my_timer.start(2000);
})
})
由于QTimer的控制函数本身就是slot,因此完全可以在JavaScript中启动它。
三、总结
本系列文章就告一段落,下面总结一下在WebUI中Python和JavaScript混合通信的方法要点:
1. 运行JavaScript,以及HTML5等需要一个浏览器容器。最新版的PyQt是一个很好的选择。
2. 使用Qt提供的QWebChannel将Python Object(实际上是QObject)与JavaScript对象连接在了一起。
3. JavaScript一端的对象可以呼叫Python Object的Slot函数,注意使用pyqtSlot修饰符
4. Python Object一端的对象可以使用Qt信号机制调用JavaScript端的函数,调用过程是异步的
最后,需要特别说明的是,QWebChannel所绑定的客户端一旦启动(在本例中是启动网页index.html),它就无法再注册新的Python Object了。因此webui中所有能调用的Python后台必须在网页启动前初始化完毕。因此,在JavaScript中动态的创建一个Python Object并注册回QWebChannel是不可以实现的void QWebChannel::registerObject(const QString &id, QObject *object)
Registers a single object to the QWebChannel.
The properties, signals and public methods of the object are published to the remote clients. There, an object with the identifier id is then constructed.
Note:A current limitation is that objects must be registered before any client is initialized.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。