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

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

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

瀏覽:77日期: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://m.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久久,三上悠亚国产精品一区二区三区
日韩一区二区三区精品 | 欧美一区成人| 99精品在线| 99免费精品| 亚洲一区免费| 日韩手机在线| 国产精品久久久一区二区| 7m精品国产导航在线| 欧美成人精品午夜一区二区| 精品视频97| 久久国产日韩| 性色av一区二区怡红| 蜜桃视频一区二区| 综合五月婷婷| 国产欧美亚洲一区| 国产一区二区亚洲| 欧美日韩水蜜桃| 亚洲一区二区三区中文字幕在线观看| 玖玖玖国产精品| 欧美久久香蕉| 偷拍精品精品一区二区三区| 欧美不卡视频| 奇米狠狠一区二区三区| 成人台湾亚洲精品一区二区| 亚洲国产专区| 日韩高清一区在线| 日本午夜大片a在线观看| 香蕉精品999视频一区二区| 欧美一区成人| 日韩精品看片| 亚州精品视频| 日韩一区欧美| 亚洲精品在线国产| 国产精品日韩精品中文字幕| 日韩一区二区在线免费| 蜜桃视频在线观看一区二区| 精品精品99| 视频一区免费在线观看| 国产精品黄色片| 欧美不卡视频| 国产精品porn| 国产视频一区欧美| 国产成年精品| 亚洲一区二区三区在线免费| 亚洲女同av| 午夜亚洲福利| 久久三级视频| 国产精品啊啊啊| 欧美日韩中文字幕一区二区三区| 久久狠狠久久| 99在线观看免费视频精品观看| 国产精品美女久久久久久不卡| 亚洲欧美日本日韩| 亚洲天堂av影院| 久久精品999| 久久国产成人| 久久精品国产99久久| 国产精品videosex极品| 在线免费观看亚洲| 亚洲男女av一区二区| 国产一区二区三区四区五区| 亚洲人成在线影院| 黄色免费成人| 国内在线观看一区二区三区 | 久久久水蜜桃av免费网站| 日韩在线观看中文字幕| 99久精品视频在线观看视频| 国产精品2区| 日产欧产美韩系列久久99| 亚洲91视频| 国产成人精品亚洲线观看| 亚洲男人在线| 亚洲免费高清| 亚洲va中文在线播放免费| 国产精品日韩精品中文字幕| 亚洲精品激情| 午夜欧美精品| 午夜av成人| 欧美亚洲日本精品| 97精品国产一区二区三区| 免费久久99精品国产自在现线| 麻豆精品视频在线观看| 视频一区视频二区中文| 婷婷激情图片久久| 欧洲精品一区二区三区| 亚洲国产专区校园欧美| 日韩和的一区二在线| 国产一区精品福利| 美女性感视频久久| 免费看一区二区三区| 欧美亚洲综合视频| 午夜亚洲福利| 亚洲综合日本| 男女性色大片免费观看一区二区 | 国产色99精品9i| 亚洲日本久久| 午夜久久av| 日本精品在线播放| 日韩精品电影一区亚洲| 亚洲区国产区| 日韩美女精品| 欧美一区激情| 国产精品欧美三级在线观看| 亚洲精品一级二级三级| 午夜日韩影院| 久久国产三级| 国产精品久久久久久模特| 国产精品久久久网站| 麻豆精品久久久| 国产va在线视频| 久久影院一区| 亚洲欧美日韩国产综合精品二区 | 国产精品亚洲片在线播放| 久久国产视频网| 国产精品视频一区二区三区四蜜臂| 国产日韩高清一区二区三区在线 | 日韩精品专区| 欧美午夜精彩| 99视频一区| 亚洲精品福利| 久久精品99国产精品日本| 国产高清视频一区二区| 久久这里只有精品一区二区| 国产成人精品一区二区免费看京 | 美女尤物国产一区| 91视频精品| 亚洲午夜在线| 免费在线看一区| 国产精品一区二区中文字幕| 91亚洲国产| 宅男在线一区| 亚洲人成精品久久久| 精品少妇一区| 91久久午夜| 国产日韩中文在线中文字幕 | 亚洲黄色网址| 红桃视频国产一区| 久久激情五月激情| 欧美日韩国产v| 亚洲综合中文| 国产一区二区视频在线看| 最新日韩欧美| 国产精品一区二区三区四区在线观看 | 欧美日韩网址| 日韩在线不卡| 日本一区二区三区中文字幕| 国产精品成人一区二区不卡| 9色精品在线| 麻豆精品久久| 日本欧洲一区二区| а√在线中文在线新版| 免费成人av在线播放| 久久a爱视频| 在线一区免费观看| 国产一区二区三区精品在线观看 | 日本在线精品| 日韩高清在线不卡| 91精品亚洲| 国产日韩在线观看视频| 国产精品99免费看| 美女久久99| 中文字幕日韩欧美精品高清在线| 精品视频97| 亚洲ww精品| 日韩深夜视频| 国产免费av一区二区三区| 91精品婷婷色在线观看| 欧美日韩亚洲三区| 视频一区二区三区入口| 久久久久97| 亚洲人成网77777色在线播放| 日韩欧美精品| 久久一区国产| 日本三级亚洲精品| 亚洲欧美日韩视频二区| 国产成人调教视频在线观看| 日本亚洲不卡| 午夜av一区| 98精品视频| 国产精品主播| 一本一道久久a久久| 亚洲欧美日韩高清在线| 国产色播av在线| 国产精品男女| 欧美日中文字幕| 精品国产美女a久久9999| 7777精品| 亚洲精品高潮| 视频一区二区中文字幕| 激情综合网站| 99成人超碰| 日韩大片在线| 国产一区二区三区不卡视频网站| 国产乱人伦精品一区| 日韩高清国产一区在线| 日韩精品一区第一页| 日韩视频久久| 亚洲美洲欧洲综合国产一区| 国产综合视频| 国产美女高潮在线观看|