日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

python GUI庫圖形界面開發之PyQt5中QWebEngineView內嵌網頁與Python的數據交互傳參詳細方法實例

瀏覽:75日期:2022-08-05 18:28:51

這幾天研究了下PyQt5中QWebEngineView內嵌網頁與Python的數據交互,今天把實例方法與代碼發布出來供大家參數

數據交互需要load進一個網頁,這里我選擇load進一個本地html網頁:JSTest.html。

同時,QWebEngineView與外面的交互還需要Qt官方提供的一個js文件:qwebchannel.js,這個文件可以在網上下載。

JSTest.html和qwebchannel.js兩個文件放在同一個目錄下,我這邊都是放在Python工程目錄下。

qwebchannel.js:

/******************************************************************************** Copyright (C) 2016 The Qt Company Ltd.** Contact: http://www.qt.io/licensing/**** This file is part of the examples of the Qt Toolkit.**** $QT_BEGIN_LICENSE:BSD$** You may use this file under the terms of the BSD license as follows:**** 'Redistribution and use in source and binary forms, with or without** modification, are permitted provided that the following conditions are** met:** * Redistributions of source code must retain the above copyright** notice, this list of conditions and the following disclaimer.** * Redistributions in binary form must reproduce the above copyright** notice, this list of conditions and the following disclaimer in** the documentation and/or other materials provided with the** distribution.** * Neither the name of The Qt Company Ltd nor the names of its** contributors may be used to endorse or promote products derived** from this software without specific prior written permission.****** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS** 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.'**** $QT_END_LICENSE$******************************************************************************/'use strict'; var QWebChannelMessageTypes = { signal: 1, propertyUpdate: 2, init: 3, idle: 4, debug: 5, invokeMethod: 6, connectToSignal: 7, disconnectFromSignal: 8, setProperty: 9, response: 10,}; var QWebChannel = function(transport, initCallback){ if (typeof transport !== 'object' || typeof transport.send !== 'function') { console.error('The QWebChannel expects a transport object with a send function and onmessage callback property.' + ' Given is: transport: ' + typeof(transport) + ', transport.send: ' + typeof(transport.send)); return; } var channel = 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) { var data = message.data; if (typeof data === 'string') { data = JSON.parse(data); } switch (data.type) { case QWebChannelMessageTypes.signal:channel.handleSignal(data);break; case QWebChannelMessageTypes.response:channel.handleResponse(data);break; case QWebChannelMessageTypes.propertyUpdate:channel.handlePropertyUpdate(data);break; default:console.error('invalid message received:', message.data);break; } } this.execCallbacks = {}; this.execId = 0; this.exec = function(data, callback) { if (!callback) { // if no callback is given, send directly channel.send(data); return; } if (channel.execId === Number.MAX_VALUE) { // wrap channel.execId = Number.MIN_VALUE; } if (data.hasOwnProperty('id')) { console.error('Cannot exec message with property id: ' + JSON.stringify(data)); return; } data.id = channel.execId++; channel.execCallbacks[data.id] = callback; channel.send(data); }; this.objects = {}; this.handleSignal = function(message) { var object = channel.objects[message.object]; if (object) { object.signalEmitted(message.signal, message.args); } else { console.warn('Unhandled signal: ' + message.object + '::' + message.signal); } } this.handleResponse = function(message) { if (!message.hasOwnProperty('id')) { console.error('Invalid response message received: ', JSON.stringify(message)); return; } channel.execCallbacks[message.id](message.data); delete channel.execCallbacks[message.id]; } this.handlePropertyUpdate = function(message) { for (var i in message.data) { var data = message.data[i]; var object = channel.objects[data.object]; if (object) {object.propertyUpdate(data.signals, data.properties); } else {console.warn('Unhandled property update: ' + 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 (var objectName in data) { var object = new QObject(objectName, data[objectName], channel); } // now unwrap properties, which might reference other registered objects for (var objectName in channel.objects) { channel.objects[objectName].unwrapProperties(); } if (initCallback) { initCallback(channel); } channel.exec({type: QWebChannelMessageTypes.idle}); });}; function QObject(name, data, webChannel){ this.__id__ = name; webChannel.objects[name] = this; // List of callbacks that get invoked upon signal emission this.__objectSignals__ = {}; // Cache of all properties, updated when a notify signal is emitted this.__propertyCache__ = {}; var object = this; // ---------------------------------------------------------------------- this.unwrapQObject = function(response) { if (response instanceof Array) { // support list of objects var ret = new Array(response.length); for (var i = 0; i < response.length; ++i) {ret[i] = object.unwrapQObject(response[i]); } return ret; } if (!response || !response['__QObject*__'] || response.id === undefined) { return response; } var objectId = response.id; if (webChannel.objects[objectId]) return webChannel.objects[objectId]; if (!response.data) { console.error('Cannot unwrap unknown QObject ' + objectId + ' without data.'); return; } var qObject = new QObject( objectId, response.data, webChannel ); qObject.destroyed.connect(function() { if (webChannel.objects[objectId] === qObject) {delete webChannel.objects[objectId];// reset the now deleted QObject to an empty {} object// just assigning {} though would not have the desired effect, but the// below also ensures all external references will see the empty map// NOTE: this detour is necessary to workaround QTBUG-40021var propertyNames = [];for (var propertyName in qObject) { propertyNames.push(propertyName);}for (var idx in propertyNames) { delete qObject[propertyNames[idx]];} } }); // here we are already initialized, and thus must directly unwrap the properties qObject.unwrapProperties(); return qObject; } this.unwrapProperties = function() { for (var propertyIdx in object.__propertyCache__) { object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]); } } function addSignal(signalData, isPropertyNotifySignal) { var signalName = signalData[0]; var signalIndex = signalData[1]; object[signalName] = { connect: function(callback) {if (typeof(callback) !== 'function') { console.error('Bad callback given to connect to signal ' + signalName); return;} object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];object.__objectSignals__[signalIndex].push(callback); if (!isPropertyNotifySignal && signalName !== 'destroyed') { // only required for 'pure' signals, handled separately for properties in propertyUpdate // also note that we always get notified about the destroyed signal webChannel.exec({ type: QWebChannelMessageTypes.connectToSignal, object: object.__id__, signal: signalIndex });} }, disconnect: function(callback) {if (typeof(callback) !== 'function') { console.error('Bad callback given to disconnect from signal ' + signalName); return;}object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];var idx = object.__objectSignals__[signalIndex].indexOf(callback);if (idx === -1) { console.error('Cannot find connection of signal ' + signalName + ' to ' + callback.name); return;}object.__objectSignals__[signalIndex].splice(idx, 1);if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) { // only required for 'pure' signals, handled separately for properties in propertyUpdate webChannel.exec({ type: QWebChannelMessageTypes.disconnectFromSignal, object: object.__id__, signal: signalIndex });} } }; } /** * Invokes all callbacks for the given signalname. Also works for property notify callbacks. */ function invokeSignalCallbacks(signalName, signalArgs) { var connections = object.__objectSignals__[signalName]; if (connections) { connections.forEach(function(callback) {callback.apply(callback, signalArgs); }); } } this.propertyUpdate = function(signals, propertyMap) { // update property cache for (var propertyIndex in propertyMap) { var propertyValue = propertyMap[propertyIndex]; object.__propertyCache__[propertyIndex] = propertyValue; } for (var signalName in signals) { // Invoke all callbacks, as signalEmitted() does not. This ensures the // property cache is updated before the callbacks are invoked. invokeSignalCallbacks(signalName, signals[signalName]); } } this.signalEmitted = function(signalName, signalArgs) { invokeSignalCallbacks(signalName, signalArgs); } function addMethod(methodData) { var methodName = methodData[0]; var methodIdx = methodData[1]; object[methodName] = function() { var args = []; var callback; for (var i = 0; i < arguments.length; ++i) {if (typeof arguments[i] === 'function') callback = arguments[i];else args.push(arguments[i]); } webChannel.exec({'type': QWebChannelMessageTypes.invokeMethod,'object': object.__id__,'method': methodIdx,'args': args }, function(response) {if (response !== undefined) { var result = object.unwrapQObject(response); if (callback) { (callback)(result); }} }); }; } function bindGetterSetter(propertyInfo) { var propertyIndex = propertyInfo[0]; var propertyName = propertyInfo[1]; var notifySignalData = propertyInfo[2]; // initialize property cache with current value // NOTE: if this is an object, it is not directly unwrapped as it might // reference other QObject that we do not know yet object.__propertyCache__[propertyIndex] = propertyInfo[3]; if (notifySignalData) { if (notifySignalData[0] === 1) {// signal name is optimized away, reconstruct the actual namenotifySignalData[0] = propertyName + 'Changed'; } addSignal(notifySignalData, true); } Object.defineProperty(object, propertyName, { configurable: true, get: function () {var propertyValue = object.__propertyCache__[propertyIndex];if (propertyValue === undefined) { // This shouldn’t happen console.warn('Undefined value in property cache for property '' + propertyName + '' in object ' + object.__id__);} return propertyValue; }, set: function(value) {if (value === undefined) { console.warn('Property setter for ' + propertyName + ' called with undefined value!'); return;}object.__propertyCache__[propertyIndex] = value;webChannel.exec({ 'type': QWebChannelMessageTypes.setProperty, 'object': object.__id__, 'property': propertyIndex, 'value': value}); } }); } // ---------------------------------------------------------------------- data.methods.forEach(addMethod); data.properties.forEach(bindGetterSetter); data.signals.forEach(function(signal) { addSignal(signal, false); }); for (var name in data.enums) { object[name] = data.enums[name]; }} //required for use with nodejsif (typeof module === ’object’) { module.exports = { QWebChannel: QWebChannel };}

Python主函數代碼

import sysimport Web_UIfrom PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import QObject,pyqtPropertyfrom PyQt5.QtWebChannel import QWebChannelfrom MySharedObject import MySharedObjectfrom PyQt5.QtWidgets import QApplicationimport osBASE_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文件)

from PyQt5.QtCore import QObjectfrom PyQt5.QtCore import pyqtPropertyfrom PyQt5.QtWidgets import QWidget,QMessageBoxclass MySharedObject(QWidget): def __init__(self,strval = ’100’): super(MySharedObject,self).__init__() self.strval = strval def _getStrValue(self): return self.strval def _setStrValue(self,str): self.strval = str print(’獲得頁面參數:%s’% str) QMessageBox.information(self,'Infomation', ’獲得的頁面參數%s’ % str) #需要定義的對外發布的方法 strValue= pyqtProperty(str,_getStrValue,_setStrValue)

頁面代碼HTML

<!DOCTYPE html> <html> <head><meta charset='UTF-8'><title>A Demo Page</title><script src = 'http://www.b3g6.com/bcjs/qwebchannel.js'></script><script language = 'javascript'> function completeAndReturnName(){ var fname = document.getElementById(’fname’).value; var lname = document.getElementById(’lname’).value; var fullname = fname +’ ’+ lname; document.getElementById(’fullname’).value = fullname; document.getElementById(’submit-btn’).style.display = ’block’; return fullname; } document.addEventListener('DOMContentLoaded',function(){ new QWebChannel(qt.webChannelTransport, function (channel) { //alert(’111 chanel=’+channel) window.bridge = channel.objects.bridge; alert(’bridge=’+bridge.strValue +’n從pyqt傳來的參數=’+window.bridge.strValue); //alert(’111 chanel=’+ channel.objects.strValue) }) } ) function onShowMsgBox() { if(window.bridge != null){ var fname = document.getElementById(’fname’).value; window.bridge.strValue = fname; //調用對象 } }</script> </head> <body><form> <label id = 'name'>User Name:</label> <input type = 'text' name = 'fname' id = 'fname'></input> <br /> <input type = 'button' value='傳遞參數到pyqt' οnclick='onShowMsgBox()'></input> <br /> <input type = 'reset' value='重置'></input></form> </body> </html>

實現效果

python GUI庫圖形界面開發之PyQt5中QWebEngineView內嵌網頁與Python的數據交互傳參詳細方法實例

python GUI庫圖形界面開發之PyQt5中QWebEngineView內嵌網頁與Python的數據交互傳參詳細方法實例

本文詳細介紹了PyQt5中使用QWebEngineView控件內嵌網頁與Python的數據交互的方法與實例,更多關于這方面的知識請查看下面的相關鏈接

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲精品麻豆| 国产在线观看www| 国产亚洲久久| 免费日韩成人| 国产剧情一区| 久久精品国产99| 亚洲一区二区三区久久久| 国产探花一区| 蜜臀久久99精品久久久久久9| 嫩呦国产一区二区三区av| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲精品成人图区| 国产精品毛片在线| 中文字幕亚洲精品乱码| 亚洲久久在线| 久久不见久久见中文字幕免费| 国产精品66| 老司机精品在线| 激情综合网址| 国产精品久久久久久久久久妞妞| 日本亚洲最大的色成网站www| 国产亚洲欧美日韩精品一区二区三区 | 伊人久久亚洲热| 亚洲97av| 亚洲www啪成人一区二区| 免费视频一区二区| av资源中文在线| 亚洲精品乱码| 国产精品极品在线观看| 尤物网精品视频| 国产不卡av一区二区| 亚洲欧美网站在线观看| 欧美日韩精品免费观看视欧美高清免费大片 | 夜久久久久久| 日韩视频网站在线观看| 日韩动漫一区| 国产一区二区三区久久| 免费日韩精品中文字幕视频在线| 国内自拍视频一区二区三区| 日韩不卡在线| 久久久一二三| 91视频久久| 国产精品美女久久久久久不卡| 国产精品国产三级国产在线观看| 亚洲一级高清| 国产精品宾馆| 在线国产一区二区| 九九99久久精品在免费线bt| 亚洲午夜久久| 国产精选久久| 国产一区清纯| 国产一区二区三区视频在线| 亚洲播播91| 精品久久在线| 午夜精品免费| 91精品91| 99精品美女| 国产香蕉精品| 日韩黄色大片| 日韩中文视频| 精品三级在线| 精品欧美激情在线观看| 久久毛片亚洲| 电影亚洲精品噜噜在线观看| 麻豆精品久久久| 欧美日韩中文一区二区| 国产日韩高清一区二区三区在线| 国产成人精品福利| av一区在线| 丝袜诱惑制服诱惑色一区在线观看| 欧美日韩午夜电影网| 日本成人手机在线| 亚洲自啪免费| 日韩激情av在线| 日欧美一区二区| 91成人精品在线| 国产精品网址| 欧美日韩国产观看视频| 久久gogo国模啪啪裸体| 欧美一级二级三级视频| 美女视频黄久久| 亚洲国产专区| 亚洲精品极品| 日本一区二区免费高清| | 视频一区在线视频| 国产一区亚洲| 日本三级亚洲精品| 日韩精品一区二区三区免费观影| 国产午夜久久| 精品一区二区三区中文字幕在线| 日韩电影免费网站| 中文字幕一区二区精品区| 国产精品久久乐| 欧美.日韩.国产.一区.二区| 国产日韩在线观看视频| 国产成人精品亚洲日本在线观看| 蜜桃视频一区二区| 欧美天堂一区二区| 激情视频一区二区三区| 日本不卡的三区四区五区| 国产夫妻在线| 欧美精品三级在线| 免费视频亚洲| 91麻豆国产自产在线观看亚洲| 久久xxxx精品视频| 色爱综合网欧美| 久久男人天堂| 国产精品地址| 中文字幕av亚洲精品一部二部| 性感美女一区二区在线观看| 免费在线小视频| 精品三级av| 日韩激情一区二区| 亚洲天堂日韩在线| 欧美综合另类| sm久久捆绑调教精品一区| 国产精品午夜一区二区三区| 亚洲精品婷婷| 中文字幕亚洲精品乱码| 蜜臀国产一区二区三区在线播放| 久久亚洲国产| 性欧美xxxx免费岛国不卡电影| 欧美一区久久久| se01亚洲视频| 国产综合婷婷| 国产精品丝袜xxxxxxx| 99香蕉国产精品偷在线观看 | 欧美aⅴ一区二区三区视频| 国产精品亚洲综合在线观看| 欧美一区二区三区久久精品| 精品午夜视频| 成人在线免费观看91| 久久精品免费一区二区三区| 久久国产中文字幕| 美女久久一区| 日韩av网站在线观看| 国产精品亚洲二区| 国产suv精品一区二区四区视频 | 国产精选在线| 欧美+日本+国产+在线a∨观看| 亚洲欧美高清| 欧美亚洲福利| 精品成人免费一区二区在线播放| 欧美综合另类| 91精品国产一区二区在线观看| 久久久久国产精品一区二区| 久久国产99| 久久午夜影院| 午夜电影亚洲| 久久黄色影视| 999国产精品| 亚洲乱码视频| 美女视频网站久久| 亚洲免费一区二区| 国产毛片精品| 国产婷婷精品| 精品三级久久| 国产日韩中文在线中文字幕| 欧美日韩国产一区精品一区| 嫩呦国产一区二区三区av| 亚洲最大av| 久久亚洲成人| 国际精品欧美精品| 天使萌一区二区三区免费观看| 麻豆精品视频在线观看视频| 视频一区二区中文字幕| se01亚洲视频| 国产精品高清一区二区| 亚洲三级网址| 久久成人一区| 激情自拍一区| 丰满少妇一区| 久久激情综合网| 免费不卡在线视频| 亚洲一区网站| 蜜臀91精品国产高清在线观看| av免费不卡国产观看| 欧美成人一二区| 国产精品麻豆成人av电影艾秋| 午夜亚洲福利| 亚洲深夜福利在线观看| 久久国产福利| 国产精品一区二区精品视频观看| 国产综合欧美| 中文字幕在线看片| 97精品久久| 少妇精品久久久一区二区| 国产亚洲在线观看| 九九在线精品| 成人av二区| 在线成人直播| 夜夜精品视频| 人人精品亚洲| 亚洲自啪免费| 免费久久99精品国产| 亚洲深夜av| 免费视频一区二区| 视频一区欧美精品| 一区二区国产精品|