python GUI库图形界面开发之PyQt5中QWebEngineView内嵌网页与Python的数据交互传参详细方法实例
这几天研究了下PyQt5中QWebEngineView内嵌网页与Python的数据交互,今天把实例方法与代码发布出来供大家参数
数据交互需要load进一个网页,这里我选择load进一个本地html网页:JSTest.html。
同时,QWebEngineView与外面的交互还需要Qt官方提供的一个js文件:qwebchannel.js,这个文件可以在网上下载。
JSTest.html和qwebchannel.js两个文件放在同一个目录下,我这边都是放在Python工程目录下。
qwebchannel.js:
/****************************************************************************
**
**Copyright(C)2016TheQtCompanyLtd.
**Contact:http://www.qt.io/licensing/
**
**ThisfileispartoftheexamplesoftheQtToolkit.
**
**$QT_BEGIN_LICENSE:BSD$
**YoumayusethisfileunderthetermsoftheBSDlicenseasfollows:
**
**"Redistributionanduseinsourceandbinaryforms,withorwithout
**modification,arepermittedprovidedthatthefollowingconditionsare
**met:
***Redistributionsofsourcecodemustretaintheabovecopyright
**notice,thislistofconditionsandthefollowingdisclaimer.
***Redistributionsinbinaryformmustreproducetheabovecopyright
**notice,thislistofconditionsandthefollowingdisclaimerin
**thedocumentationand/orothermaterialsprovidedwiththe
**distribution.
***NeitherthenameofTheQtCompanyLtdnorthenamesofits
**contributorsmaybeusedtoendorseorpromoteproductsderived
**fromthissoftwarewithoutspecificpriorwrittenpermission.
**
**
**THISSOFTWAREISPROVIDEDBYTHECOPYRIGHTHOLDERSANDCONTRIBUTORS
**"ASIS"ANDANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOT
**LIMITEDTO,THEIMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFOR
**APARTICULARPURPOSEAREDISCLAIMED.INNOEVENTSHALLTHECOPYRIGHT
**OWNERORCONTRIBUTORSBELIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,
**SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOT
**LIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,
**DATA,ORPROFITS;ORBUSINESSINTERRUPTION)HOWEVERCAUSEDANDONANY
**THEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,ORTORT
**(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSE
**OFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE."
**
**$QT_END_LICENSE$
**
****************************************************************************/
"usestrict";
varQWebChannelMessageTypes={
signal:1,
propertyUpdate:2,
init:3,
idle:4,
debug:5,
invokeMethod:6,
connectToSignal:7,
disconnectFromSignal:8,
setProperty:9,
response:10,
};
varQWebChannel=function(transport,initCallback)
{
if(typeoftransport!=="object"||typeoftransport.send!=="function"){
console.error("TheQWebChannelexpectsatransportobjectwithasendfunctionandonmessagecallbackproperty."+
"Givenis:transport:"+typeof(transport)+",transport.send:"+typeof(transport.send));
return;
}
varchannel=this;
this.transport=transport;
this.send=function(data)
{
if(typeof(data)!=="string"){
data=JSON.stringify(data);
}
channel.transport.send(data);
}
this.transport.onmessage=function(message)
{
vardata=message.data;
if(typeofdata==="string"){
data=JSON.parse(data);
}
switch(data.type){
caseQWebChannelMessageTypes.signal:
channel.handleSignal(data);
break;
caseQWebChannelMessageTypes.response:
channel.handleResponse(data);
break;
caseQWebChannelMessageTypes.propertyUpdate:
channel.handlePropertyUpdate(data);
break;
default:
console.error("invalidmessagereceived:",message.data);
break;
}
}
this.execCallbacks={};
this.execId=0;
this.exec=function(data,callback)
{
if(!callback){
//ifnocallbackisgiven,senddirectly
channel.send(data);
return;
}
if(channel.execId===Number.MAX_VALUE){
//wrap
channel.execId=Number.MIN_VALUE;
}
if(data.hasOwnProperty("id")){
console.error("Cannotexecmessagewithpropertyid:"+JSON.stringify(data));
return;
}
data.id=channel.execId++;
channel.execCallbacks[data.id]=callback;
channel.send(data);
};
this.objects={};
this.handleSignal=function(message)
{
varobject=channel.objects[message.object];
if(object){
object.signalEmitted(message.signal,message.args);
}else{
console.warn("Unhandledsignal:"+message.object+"::"+message.signal);
}
}
this.handleResponse=function(message)
{
if(!message.hasOwnProperty("id")){
console.error("Invalidresponsemessagereceived:",JSON.stringify(message));
return;
}
channel.execCallbacks[message.id](message.data);
deletechannel.execCallbacks[message.id];
}
this.handlePropertyUpdate=function(message)
{
for(variinmessage.data){
vardata=message.data[i];
varobject=channel.objects[data.object];
if(object){
object.propertyUpdate(data.signals,data.properties);
}else{
console.warn("Unhandledpropertyupdate:"+data.object+"::"+data.signal);
}
}
channel.exec({type:QWebChannelMessageTypes.idle});
}
this.debug=function(message)
{
channel.send({type:QWebChannelMessageTypes.debug,data:message});
};
channel.exec({type:QWebChannelMessageTypes.init},function(data){
for(varobjectNameindata){
varobject=newQObject(objectName,data[objectName],channel);
}
//nowunwrapproperties,whichmightreferenceotherregisteredobjects
for(varobjectNameinchannel.objects){
channel.objects[objectName].unwrapProperties();
}
if(initCallback){
initCallback(channel);
}
channel.exec({type:QWebChannelMessageTypes.idle});
});
};
functionQObject(name,data,webChannel)
{
this.__id__=name;
webChannel.objects[name]=this;
//Listofcallbacksthatgetinvokeduponsignalemission
this.__objectSignals__={};
//Cacheofallproperties,updatedwhenanotifysignalisemitted
this.__propertyCache__={};
varobject=this;
//----------------------------------------------------------------------
this.unwrapQObject=function(response)
{
if(responseinstanceofArray){
//supportlistofobjects
varret=newArray(response.length);
for(vari=0;i
Python主函数代码
importsys
importWeb_UI
fromPyQt5importQtCore,QtGui,QtWidgets
fromPyQt5.QtCoreimportQObject,pyqtProperty
fromPyQt5.QtWebChannelimportQWebChannel
fromMySharedObjectimportMySharedObject
fromPyQt5.QtWidgetsimportQApplication
importos
BASE_DIR=os.path.dirname(__file__)#获取当前文件夹的绝对路径
if__name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
MainWindow=QtWidgets.QFrame()
ui=Web_UI.Ui_Form()
ui.setupUi(MainWindow)
ui.webView1.load(QtCore.QUrl(r""+BASE_DIR+"/JSTest.html"))
channel=QWebChannel()##创建一个QwebChannel对象,用于传递PyQt的参数到JavaScript
myObj=MySharedObject()
print(myObj.strval)
channel.registerObject('bridge',myObj)
ui.webView1.page().setWebChannel(channel)
MainWindow.show()
sys.exit(app.exec_())
继承了QWidget类的MySharedObject(Python文件)
fromPyQt5.QtCoreimportQObject
fromPyQt5.QtCoreimportpyqtProperty
fromPyQt5.QtWidgetsimportQWidget,QMessageBox
classMySharedObject(QWidget):
def__init__(self,strval='100'):
super(MySharedObject,self).__init__()
self.strval=strval
def_getStrValue(self):
returnself.strval
def_setStrValue(self,str):
self.strval=str
print('获得页面参数:%s'%str)
QMessageBox.information(self,"Infomation",'获得的页面参数%s'%str)
#需要定义的对外发布的方法
strValue=pyqtProperty(str,_getStrValue,_setStrValue)
页面代码HTML
ADemoPage
functioncompleteAndReturnName(){
varfname=document.getElementById('fname').value;
varlname=document.getElementById('lname').value;
varfullname=fname+''+lname;
document.getElementById('fullname').value=fullname;
document.getElementById('submit-btn').style.display='block';
returnfullname;
}
document.addEventListener("DOMContentLoaded",function(){
newQWebChannel(qt.webChannelTransport,function(channel){
//alert('111chanel='+channel)
window.bridge=channel.objects.bridge;
alert('bridge='+bridge.strValue+'\n从pyqt传来的参数='+window.bridge.strValue);
//alert('111chanel='+channel.objects.strValue)
})
})
functiononShowMsgBox(){
if(window.bridge!=null){
varfname=document.getElementById('fname').value;
window.bridge.strValue=fname;//调用对象
}
}
实现效果
本文详细介绍了PyQt5中使用QWebEngineView控件内嵌网页与Python的数据交互的方法与实例,更多关于这方面的知识请查看下面的相关链接
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。