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;iPython主函数代码
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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。