当前位置:网站首页>PyQt5快速开发与实战 5.4 网页交互
PyQt5快速开发与实战 5.4 网页交互
2022-07-28 19:48:00 【Ding Jiaxiong】
PyQt5快速开发与实战
文章目录
5. 第5章 PyQt5 高级界面控件
5.4 网页交互
PyQt 5使用QWebEngineView控件来展示HTML 页面,对老版本中的QWebView类不再进行维护,因为 QWebEngineView使用 Chromium内核可以给用户带来更好的体验。
Qt慢慢淘汰了古老的 WebKit,取而代之的是使用WebEngine框架。WebEngine是基于谷歌的 Chromium引擎开发的,也就是内部集成了谷歌的Chromium引擎。WebEngine框架是基于Chromium上的 Content API封装,投入成本比较小,可以很好地支持HTML 5。
在PyQt5中可以通过 PyQt5.QtWebKitWidgets.QWebEngineView类来使用网页控件
Qobject → QLayout → QWidget → QWenEngineView
5.4.1 QWebEngineView类中的常用方法
| 方法 | 描述 |
|---|---|
| load(QUrl url) | 加载指定的URL并显示 |
| setHtml(QString &html) | 将网页视图的内容设置为指定的HTML内容 |
OWebEngineView控件使用load()函数加载一个 Web页面,实际上就是使用HTTP GET方法加载 Web页面。这个控件既可以加载本地的Web页面也可以加载远程的外部 Web页面。
先要自行安装
pip install PyQtWebEngine -i https://pypi.tuna.tsinghua.edu.cn/simple

from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import *
view = QWebEngineView()
view.load(QUrl("https://blog.csdn.net/weixin_44226181?type=blog"))
view.show()
5.4.2 案例——加载并显示外部的Web页面
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("打开外部网页案例")
self.setGeometry(5,30,1355,730)
self.browser = QWebEngineView()
self.browser.load(QUrl("https://blog.csdn.net/weixin_44226181?type=blog"))
self.setCentralWidget(self.browser)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())

5.4.3 案例——加载并显示本地的Web页面
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("打开本地页面案例")
self.setGeometry(5,30,555,330)
self.browser = QWebEngineView()
url = r'D:/DingJiaxiong/PycharmProjects/PyQt5Study/网页交互/index.html'
self.browser.load(QUrl(url))
self.setCentralWidget(self.browser)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())

5.4.4 案例——加载并显示嵌入的HTML代码
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("打开本地页面HTML代码案例")
self.setGeometry(5, 30, 555, 330)
self.browser = QWebEngineView()
self.browser.setHtml(""" <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>丁家雄!</title> </head> <body> <h1> Hello,DingJiaxiong! </h1> </body> </html> """)
self.setCentralWidget(self.browser)
if __name__ == '__main__':
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())

经过测试,使用 QWebEngine View对象的setHtml())函数渲染HTML页面时,如果页面中使用的JavaScript代码超过2MB,程序渲染的页面就会渲染失败,页面中会出现大片的空白。
5.4.5 案例——PyQt调用JavaScript代码
通过 QWebEnginePage类的 runJavaScript(str, Callable)函数可以很方便地实现PyQt和 HTML/JavaScript的双向通信,也实现了Python 代码和 HTML/JavaScript 代码的解耦,便于开发人员进行分工协作。
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt5.QtWebEngineWidgets import QWebEngineView
import sys
from pyqt5_plugins.examples.exampleqmlitem import QtCore
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
# 创建一个 application实例
app = QApplication(sys.argv)
win = QWidget()
win.setWindowTitle('Web页面中的JavaScript与 QWebEngineView交互例子')
# 创建一个垂直布局器
layout = QVBoxLayout()
win.setLayout(layout)
# 创建一个 QWebEngineView 对象
view = QWebEngineView()
view.setHtml(''' <html> <head> <title>A Demo Page</title> <script language="javascript"> // Completes the full-name control and // shows the submit button function completeAndReturnName() { var fname = document.getElementById('fname').value; var lname = document.getElementById('lname').value; var full = lname + ' ' + fname; document.getElementById('fullname').value = full; document.getElementById('submit-btn').style.display = 'block'; return full; } </script> </head> <body> <form> <label for="fname">First name:</label> <input type="text" name="fname" id="fname"></input> <br /> <label for="lname">Last name:</label> <input type="text" name="lname" id="lname"></input> <br /> <label for="fullname">Full name:</label> <input disabled type="text" name="fullname" id="fullname"></input> <br /> <input style="display: none;" type="submit" id="submit-btn"></input> </form> </body> </html> ''')
# 创建一个按钮去调用 JavaScript代码
button = QPushButton('设置全名')
def js_callback(result):
print(result)
def complete_name():
view.page().runJavaScript('completeAndReturnName();', js_callback)
# 按钮连接 'complete_name'槽,当点击按钮是会触发信号
button.clicked.connect(complete_name)
# 把QWebView和button加载到layout布局中
layout.addWidget(view)
layout.addWidget(button)
# 显示窗口和运行app
win.show()
sys.exit(app.exec_())

5.4.6 案例——JavaScript调用PyQt代码
JavaScript调用PyOt代码,是指PyOt可以与加载的 Web页面进行双向的数据交互。首先,使用QWebEngineView对象加载Web页面后,就可以获得页面中表单输入数据,在Web页面中通过JavaScript 代码收集用户提交的数据。然后,在 Web页面中,JavaScript通过桥连接方式传递数据给PyQt。最后,PyQt 接收到页面传递的数据,经过业务处理后,还可以把处理过的数据返给Web页面。
创建QWebChannel对象
创建QWebChannel对象,注册一个需要桥接的对象,以便Web页面的JavaScript使用。
channel = QWebChannel() myobj = MySharedObject() channel.registerObject("bridge",myobj) view.page().setWebChannel(channel)创建共享数据的PyQt对象
class MySharcedObject(QWidget): def __init__(self): super(MySharcedObject, self).__init__() def _setStrValue(self,str): print("获得页面参数: %s" % str) # 定义对外发布的方法 strValue = pyqtProperty(str,fset = _setStrValue)对外提供的 PyOt对象方法,需要使用pyqtProperty()函数让它暴露出来。
在PyQt5中使用pyqtProperty()函数来定义PyQt对象中的属性,这个函数的使用方式与标准Python模块中的property()函数相同。PyQt5.QtCore.pyqtProperty()函数的API如下:
PyQt5.Qtcore.pyqtProperty(type[, fget=None[,fset=None[, freset=None [,fdel=None[, doc=None[, designable=True[, scriptable=True[, stored=True[,user=False[,constant=False[, final=False[,notify=None [, revision=0]]]]]]]]])参数说明
参数 说明 type 必填,属性的类型 fget 可选,用于获取属性的值 fset 可选,用于设置属性的值 freset 可选,用于将属性的值重置为它的默认值 fdel 可选,用于删除属性 Doc 可选,属性的文档字符串 designable 可选,设置Qt DESIGNABLE标志 scriptable 可选,设置Qt SCRIPTABLE标志 stored 可选,设置Qt STORED标志 user 可选,设置Qt USER标志 constant 可选,设置Qt CONSTANT标志 final 可选,设置Qt FINAL标志 notify 可选,未绑定的通知信号 revision 可选,将版本导出到QML 测试案例
from PyQt5.QtCore import QObject, pyqtProperty class MyObject(QObject): def __init__(self, inVal=20): self.val = inVal def readVal(self): print('readVal=%s' % self.val) return self.val def setVal(self, val): print('setVal=%s' % val) self.val = val ppVal = pyqtProperty(int, readVal, setVal) if __name__ == '__main__': obj = MyObject() print('\n#1') obj.ppVal = 10 print('\n#2') print('obj.ppVal=%s' % obj.ppVal) print('obj.readVal()=%s' % obj.readVal())
创建调用PyQt的Web页面
本机直接启动服务
<!DOCTYPE html> <html lang="en"> <head> <title>A Demo Page</title> <meta charset="UTF-8"> <script src="qwebchannel.js"></script> <script> function completeAndReturnName() { var fname = document.getElementById('fname').value; var lname = document.getElementById('lname').value; var full = lname + ' ' + fname; document.getElementById('fullname').value = full; document.getElementById('submit-btn').style.display = 'block'; return full; } document.addEventListener("DOMContentLoaded", function () { new QWebChannel(qt.webChannelTransport, function (channel) { //alert('111 channel=' + channel ) window.bridge = channel.objects.bridge; alert('bridge=' + bridge + '\n从pyqt传来的参数=' + window.bridge.strValue); }); }); function onShowMsgBox() { //alert('window.bridge=' + window.bridge); if (window.bridge) { //alert('bridge.strValue=' + window.bridge.strValue ) ; //bridge.sayHello('999') var fname = document.getElementById('fname').value; window.bridge.strValue = fname; } } </script> </head> <body> <form> <label for="姓名">user name:</label> <input type="text" name="fname" id="fname"></input> <br/> <input type="button" value="传递参数到pyqt" onclick="onShowMsgBox()"> <input type="reset" value='重置'/> </form> </body> </html>
实例
from PyQt5.QtWidgets import QApplication , QWidget , QVBoxLayout from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtCore import QUrl from MySharedObject import MySharedObject from PyQt5.QtWebChannel import QWebChannel import sys from pyqt5_plugins.examples.exampleqmlitem import QtCore QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) # 创建一个 application实例 app = QApplication(sys.argv) win = QWidget() win.setWindowTitle('Web页面中的JavaScript与 QWebEngineView交互例子') # 创建一个垂直布局器 layout = QVBoxLayout() win.setLayout(layout) # 创建一个 QWebEngineView 对象 view = QWebEngineView() htmlUrl = 'http://127.0.0.1:8000/web/index.html' view.load( QUrl( htmlUrl )) # 创建一个 QWebChannel对象,用来传递pyqt参数到JavaScript channel = QWebChannel( ) myObj = MySharedObject() channel.registerObject( "bridge", myObj ) view.page().setWebChannel(channel) # 把QWebView和button加载到layout布局中 layout.addWidget(view) # 显示窗口和运行app win.show() sys.exit(app.exec_())MySharedObject.py
from PyQt5.QtCore import QObject from PyQt5.QtCore import pyqtProperty from PyQt5.QtWidgets import QWidget,QMessageBox class MySharedObject(QWidget): def __init__( self): super( MySharedObject, self).__init__() def _getStrValue( self): # return '100' def _setStrValue( self, str ): # print('获得页面参数 :%s'% str ) QMessageBox.information(self,"Information", '获得页面参数 :%s'% str ) #需要定义对外发布的方法 strValue = pyqtProperty(str, fget=_getStrValue, fset=_setStrValue)

边栏推荐
- Eureka registers with each other, only showing each other or only showing problems in one
- 提前布局6G赛道!紫光展锐发布《6G无界 有AI》白皮书
- Redis缓存雪崩、缓存穿透、缓存击穿
- How to understand data mesh
- Learning typescript (II)
- SQL server中提示对象名无效
- The development of smart home industry pays close attention to edge computing and applet container technology
- Using El date picker to report errors in sub components
- 面向千元级5G手机市场,联发科天玑700发布
- Leetcode interview question 02.07. Linked list intersection [knowledge points: Double pointers, stack]
猜你喜欢

Kubeadm搭建kubernetes集群

Ctfshow network lost track record (2)

Young freshmen yearn for more open source | here comes the escape guide from open source to employment!

Guanghetong & Qualcomm Internet of things technology open day successfully held

Uncaught Error:Invalid geoJson format Cannot read property ‘length‘ of undefind

Coding with these 16 naming rules can save you more than half of your comments!

Two excellent software of my love cracking, batch search text, image and video image quality enhancement

证券企业基于容器化 PaaS 平台的 DevOps 规划建设 29 个典型问题总结

编码用这16个命名规则能让你少写一半以上的注释!

There have been two safety accidents in a month after listing. Is L9 ideal?
随机推荐
如何度量软件架构
关键路径的分析
Library borrowing system "suggested collection"
数据库读写分离目的是做什么[通俗易懂]
详细讲解C语言12(C语言系列)
1945. sum of digits after string conversion
1945. 字符串转化后的各位数字之和
云安全核心技术
Buuctf questions upload labs record pass-11~pass-20
SkiaSharp 之 WPF 自绘 拖曳小球(案例版)
NTP server time (view server time)
ctfshow 网络迷踪做题记录(1)
Cloud security core technology
Redis cache avalanche, cache penetration, cache breakdown
Maxwell 一款简单易上手的实时抓取Mysql数据的软件
针对下一代Chromebook,联发科推出新款芯片组MT8192和MT8195
SQL server中提示对象名无效
How does lazada store make up orders efficiently? (detailed technical explanation of evaluation self-supporting number)
SQL Server 数据库之备份和恢复数据库
Adventures of little mouse: behind the scenes gags of moss 2