亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

python GUI庫(kù)圖形界面開發(fā)之PyQt5中QWebEngineView內(nèi)嵌網(wǎng)頁(yè)與Python的數(shù)據(jù)交互傳參詳細(xì)方法實(shí)例

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

這幾天研究了下PyQt5中QWebEngineView內(nèi)嵌網(wǎng)頁(yè)與Python的數(shù)據(jù)交互,今天把實(shí)例方法與代碼發(fā)布出來(lái)供大家參數(shù)

數(shù)據(jù)交互需要load進(jìn)一個(gè)網(wǎng)頁(yè),這里我選擇load進(jìn)一個(gè)本地html網(wǎng)頁(yè):JSTest.html。

同時(shí),QWebEngineView與外面的交互還需要Qt官方提供的一個(gè)js文件:qwebchannel.js,這個(gè)文件可以在網(wǎng)上下載。

JSTest.html和qwebchannel.js兩個(gè)文件放在同一個(gè)目錄下,我這邊都是放在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主函數(shù)代碼

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__)#獲取當(dāng)前文件夾的絕對(duì)路徑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() ##創(chuàng)建一個(gè)QwebChannel對(duì)象,用于傳遞PyQt的參數(shù)到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(’獲得頁(yè)面參數(shù):%s’% str) QMessageBox.information(self,'Infomation', ’獲得的頁(yè)面參數(shù)%s’ % str) #需要定義的對(duì)外發(fā)布的方法 strValue= pyqtProperty(str,_getStrValue,_setStrValue)

頁(yè)面代碼HTML

<!DOCTYPE html> <html> <head><meta charset='UTF-8'><title>A Demo Page</title><script src = 'http://www.aoyou183.cn/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傳來(lái)的參數(shù)=’+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; //調(diào)用對(duì)象 } }</script> </head> <body><form> <label id = 'name'>User Name:</label> <input type = 'text' name = 'fname' id = 'fname'></input> <br /> <input type = 'button' value='傳遞參數(shù)到pyqt' οnclick='onShowMsgBox()'></input> <br /> <input type = 'reset' value='重置'></input></form> </body> </html>

實(shí)現(xiàn)效果

python GUI庫(kù)圖形界面開發(fā)之PyQt5中QWebEngineView內(nèi)嵌網(wǎng)頁(yè)與Python的數(shù)據(jù)交互傳參詳細(xì)方法實(shí)例

python GUI庫(kù)圖形界面開發(fā)之PyQt5中QWebEngineView內(nèi)嵌網(wǎng)頁(yè)與Python的數(shù)據(jù)交互傳參詳細(xì)方法實(shí)例

本文詳細(xì)介紹了PyQt5中使用QWebEngineView控件內(nèi)嵌網(wǎng)頁(yè)與Python的數(shù)據(jù)交互的方法與實(shí)例,更多關(guān)于這方面的知識(shí)請(qǐng)查看下面的相關(guān)鏈接

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 亚洲国产欧美日韩一区二区 | 丰满美女福利视频在线播放 | 一级毛片欧美一级日韩黄 | 人妇出轨三级香港 | 岛国在线123456 | 亚洲欧美视频 | 午夜免费福利在线 | 成人久久18免费软件 | 日本特黄特色大片免费视频 | 亚洲人成在线观看男人自拍 | 1024手机在线播放 | 国产成人高清亚洲一区久久 | 国产精品1024永久观看 | 国产精品欧美日韩一区二区 | 18岁免费网站 | 免费羞羞视频网站 | jk足控福利国产在线播放 | 国产综合福利 | 欧美国产人妖另类色视频 | 国产成人在线播放 | 国产99r视频精品免费观看 | 香港三级毛片 | 国产精品免费一级在线观看 | 伊人色综合久久天天爱 | 伊人蕉久中文字幕无码专区 | 美女被啪到深处喷水gif动态图视频 | 黄色在线视频在线观看 | 131美女爽爽爽爱做视频 | 小明看看主页 | 俄罗斯午夜影院 | 黄色免费网站在线观看 | 韩国精品一区二区三区四区五区 | 久久久久久免费一区二区三区 | 国产一区二区三区四区波多野结衣 | 美女被免费网站视频九色 | 免费的黄色毛片 | 动漫chinesehdxxxx| 美国一级片免费看 | 在线观看黄a | 欧美aaa大片 | 91精品国产乱码久久久久久 |