如果需要在程序中加载并显示网页,那QWebEngineView绝对是最佳的选择。该控件基于Chrome浏览器内核引擎,所提供的功能和方法还是比较强大的。

注:V5.11及更高版本的PyQt5中不包含QWebEngineView,请另外单独下载:

pip install PyQtWebEngine

30.1 制作简单浏览器

本章我们就通过制作下图所示的简单浏览器来了解QWebEngineView的用法:

在输入框中输入网址并敲回车后,QWebEngineView控件加载并显示相应的网址内容。左上方的三个按钮可以允许我们进行前进、后退和刷新操作,右上方的两个按钮可以放大和缩小网页。

下面我们一步步来实现,首先完成浏览器的外观:

import sys
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QVBoxLayout, QHBoxLayoutclass Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.resize(1000, 600)                  # 1self.back_btn = QPushButton(self)       # 2self.forward_btn = QPushButton(self)self.refresh_btn = QPushButton(self)self.zoom_in_btn = QPushButton(self)self.zoom_out_btn = QPushButton(self)self.url_le = QLineEdit(self)self.browser = QWebEngineView(self)self.h_layout = QHBoxLayout()self.v_layout = QVBoxLayout()self.layout_init()self.btn_init()self.le_init()def layout_init(self):                       # 3self.h_layout.setSpacing(0)self.h_layout.addWidget(self.back_btn)self.h_layout.addWidget(self.forward_btn)self.h_layout.addWidget(self.refresh_btn)self.h_layout.addStretch(2)self.h_layout.addWidget(self.url_le)self.h_layout.addStretch(2)self.h_layout.addWidget(self.zoom_in_btn)self.h_layout.addWidget(self.zoom_out_btn)self.v_layout.addLayout(self.h_layout)self.v_layout.addWidget(self.browser)self.setLayout(self.v_layout)def btn_init(self):                           # 4self.back_btn.setIcon(QIcon('images/back.png'))self.forward_btn.setIcon(QIcon('images/forward.png'))self.refresh_btn.setIcon(QIcon('images/refresh.png'))self.zoom_in_btn.setIcon(QIcon('images/zoom_in.png'))self.zoom_out_btn.setIcon(QIcon('images/zoom_out.png'))def le_init(self):                            # 5self.url_le.setFixedWidth(400)self.url_le.setPlaceholderText('Search or enter website name')if __name__ == '__main__':app = QApplication(sys.argv)demo = Demo()demo.show()sys.exit(app.exec_())

1. 通过resize()方法来将窗口大小设为1000x600;

2. 实例化按钮控件、输入框控件以及QWebEngineView控件;

3. 完成布局,使用setSpacing()传入参数0代表让各个控件之间不存在间隔(主要想让按钮靠拢),随后我们在想要的地方使用addStretch(),这样就达到让输入框和按钮分离开来,而按钮之间又是相互靠拢的目的。

4. 给按钮添加图标,图片下载地址如下:

  • back.png: https://www.easyicon.net/download/png/1117578/64/
  • forward.png: https://www.easyicon.net/download/png/1117605/64/
  • refresh.png: https://www.easyicon.net/download/png/1117668/64/
  • zoom_in.png: https://www.easyicon.net/download/png/1117715/64/
  • zoom_out.png: https://www.easyicon.net/download/png/1117716/64/

5. 设置输入框宽度为400并设置占位符提示用户在这里输入网址。

此时运行截图如下,QWebEngine还没有显示任何网页:

接下来完成以下功能:在输入框中输入网址并敲击回车后,QWebEngineView加载并显示相应的网址内容:

def keyPressEvent(self, QKeyEvent):if QKeyEvent.key() == Qt.Key_Return or QKeyEvent.key() == Qt.Key_Enter:if self.url_le.hasFocus():self.browser.load(QUrl(self.url_le.text()))

既然涉及到键盘,那肯定要用事件函数来处理了。

标准的键盘上是有两个回车键的,Key_Return为大回车,Key_Enter为小回车(这里我们把两种都考虑进来)如下图所示:

加上if self.url_le.hasFocus():判断是为了只有在输入框被编辑的状态下敲击回车才会让网页实现跳转(读者也可以去使用下市面上的浏览器看下是否是这样)。

条件都满足的话,就调用load()方法并传入一个QUrl类型参数即可(不能单单传入字符串,需要用QUrl()把字符串转为QUrl对象)。

虽然QWebEngineView已经提供了很多有用的方法,但是许多方面还是需要我们开发人员进行完善。比如用户如果只输入"http://baidu.com"的话,那QWebEngineView其实是识别不出来的,也就无法加载和显示网页了(会跳转到空白页)。

市面上的浏览器在用户只输入"http://baidu.com"的情况下,会自动在最前面加上"http://"或者“https://”,我们接下来完善下代码:

def keyPressEvent(self, QKeyEvent):if QKeyEvent.key() == Qt.Key_Return or QKeyEvent.key() == Qt.Key_Enter:if self.url_le.hasFocus():if self.url_le.text().startswith('https://') or self.url_le.text().startswith('http://'):self.browser.load(QUrl(self.url_le.text()))else:self.browser.load(QUrl('https://'+self.url_le.text()))

调用startswith()方法判断用户输入的网址字符串是否是以"https://"或者“http://”开头的,如果是的话,则采用用户输入的网址;如果不是,则在前面加上"https://"。这样的话QWebEngineView就可以正常显示了。

接下来完成以下功能:首次运行程序时,QWebEngineView显示百度网页。

def browser_init(self):self.browser.load(QUrl('https://baidu.com'))

非常简单,只需要在类初始化函数中调用以上函数即可。

到目前为止,程序代码如下:

import sys
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QVBoxLayout, QHBoxLayoutclass Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.resize(1000, 600)self.back_btn = QPushButton(self)self.forward_btn = QPushButton(self)self.refresh_btn = QPushButton(self)self.zoom_in_btn = QPushButton(self)self.zoom_out_btn = QPushButton(self)self.url_le = QLineEdit(self)self.browser = QWebEngineView()self.h_layout = QHBoxLayout()self.v_layout = QVBoxLayout()self.layout_init()self.btn_init()self.le_init()self.browser_init()def layout_init(self):self.h_layout.setSpacing(0)self.h_layout.addWidget(self.back_btn)self.h_layout.addWidget(self.forward_btn)self.h_layout.addWidget(self.refresh_btn)self.h_layout.addStretch(2)self.h_layout.addWidget(self.url_le)self.h_layout.addStretch(2)self.h_layout.addWidget(self.zoom_in_btn)self.h_layout.addWidget(self.zoom_out_btn)self.v_layout.addLayout(self.h_layout)self.v_layout.addWidget(self.browser)self.setLayout(self.v_layout)def browser_init(self):self.browser.load(QUrl('https://baidu.com'))def btn_init(self):self.back_btn.setIcon(QIcon('images/back.png'))self.forward_btn.setIcon(QIcon('images/forward.png'))self.refresh_btn.setIcon(QIcon('images/refresh.png'))self.zoom_in_btn.setIcon(QIcon('images/zoom_in.png'))self.zoom_out_btn.setIcon(QIcon('images/zoom_out.png'))def le_init(self):self.url_le.setFixedWidth(400)self.url_le.setPlaceholderText('Search or enter website name')def keyPressEvent(self, QKeyEvent):if QKeyEvent.key() == Qt.Key_Return or QKeyEvent.key() == Qt.Key_Enter:if self.url_le.hasFocus():if self.url_le.text().startswith('https://') or self.url_le.text().startswith('http://'):self.browser.load(QUrl(self.url_le.text()))else:self.browser.load(QUrl('https://'+self.url_le.text()))if __name__ == '__main__':app = QApplication(sys.argv)demo = Demo()demo.show()sys.exit(app.exec_())

我们运行一下,发现两个问题:

1. 程序首次运行时,输入框文本并没有显示百度网址。

2. 当我们在输入框中输入"http://python.org"并敲击回车后,网页可以加载,但是输入框并没有显示当前应该要显示的“https://www.python.org/”。

或者在点击页面中的“Downloads”跳转到另一个页面后,输入框的文本也应该要相应地变为“https://www.python.org/downloads/”。

根据以上问题我们知道接下来应该把输入框的文本设置为QWebEngineView所加载的网址。QWebEngineView控件有一个信号urlChanged,该信号会在每次要加载的网址发生变化时发射。那我们其实可以把这个信号和槽函数连接起来,在槽函数中我们把输入框的文本设置为变化后QWebEngineView要加载的网址即可(其他信号例如loadStarted, loadFinished等其实也可以)。

我们只需要在browser_init()函数中加一行信号和槽函数连接的代码即可:

def browser_init(self):self.browser.load(QUrl('https://baidu.com'))self.browser.urlChanged.connect(lambda: self.url_le.setText(self.browser.url().toDisplayString()))

调用QWebEngineView的url()方法获取QUrl对象,但这个不是字符串类型,所以还需要调用toDisplayString()方法来获取url文本字符串。现在再来运行下就会发现输入框的文本会跟随QWebEngineView当前加载的网址改变而改变了。

接下来我们完善按钮功能,首先是左上角的后退、前进和刷新。查看文档我们很容易就会发现QWebEngineView有几个槽函数可以实现这三个功能:

back()方法实现后退功能,forward()方法实现前进功能而reload()方法实现刷新功能。我们接下来只需要在btn_init()函数中加几行信号和槽函数连接的代码即可:

def btn_init(self):self.back_btn.setIcon(QIcon('images/back.png'))self.forward_btn.setIcon(QIcon('images/forward.png'))self.refresh_btn.setIcon(QIcon('images/refresh.png'))self.zoom_in_btn.setIcon(QIcon('images/zoom_in.png'))self.zoom_out_btn.setIcon(QIcon('images/zoom_out.png'))self.back_btn.clicked.connect(self.browser.back)self.forward_btn.clicked.connect(self.browser.forward)self.refresh_btn.clicked.connect(self.browser.reload)

此时运行下程序,就会发现程序可以像一个真正的浏览器一样后退、前进和刷新了。

最后是放大缩小功能,要实现这种功能我们需要用到zoomFactor()方法和setZoomFactor()方法。前者获取当前缩放值,后者设置缩放值。那也就是说我们每当用户点击放大或缩小按钮时,只需要先获取到当前的缩放值,然后放大的话就增加缩放值,缩小就减小缩放值。首先实现槽函数,代码如下:

def zoom_in_func(self):self.browser.setZoomFactor(self.browser.zoomFactor()+0.1)def zoom_out_func(self):self.browser.setZoomFactor(self.browser.zoomFactor()-0.1)

然后在btn_init()函数中再加两行信号和槽函数连接的代码:

def btn_init(self):self.back_btn.setIcon(QIcon('images/back.png'))self.forward_btn.setIcon(QIcon('images/forward.png'))self.refresh_btn.setIcon(QIcon('images/refresh.png'))self.zoom_in_btn.setIcon(QIcon('images/zoom_in.png'))self.zoom_out_btn.setIcon(QIcon('images/zoom_out.png'))self.back_btn.clicked.connect(self.browser.back)self.forward_btn.clicked.connect(self.browser.forward)self.refresh_btn.clicked.connect(self.browser.reload)self.zoom_in_btn.clicked.connect(self.zoom_in_func)self.zoom_out_btn.clicked.connect(self.zoom_out_func)

现在运行下程序,点击放大缩小按钮,页面就会相应的放大缩小:

​​但是放大和缩小的范围是有限定的:

根据文档我们可以知道范围为0.25-5.0,默认值是1.0。

完整代码如下:

import sys
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QVBoxLayout, QHBoxLayoutclass Demo(QWidget):def __init__(self):super(Demo, self).__init__()self.resize(1000, 600)self.back_btn = QPushButton(self)self.forward_btn = QPushButton(self)self.refresh_btn = QPushButton(self)self.zoom_in_btn = QPushButton(self)self.zoom_out_btn = QPushButton(self)self.url_le = QLineEdit(self)self.browser = QWebEngineView()self.h_layout = QHBoxLayout()self.v_layout = QVBoxLayout()self.layout_init()self.btn_init()self.le_init()self.browser_init()def layout_init(self):self.h_layout.setSpacing(0)self.h_layout.addWidget(self.back_btn)self.h_layout.addWidget(self.forward_btn)self.h_layout.addWidget(self.refresh_btn)self.h_layout.addStretch(2)self.h_layout.addWidget(self.url_le)self.h_layout.addStretch(2)self.h_layout.addWidget(self.zoom_in_btn)self.h_layout.addWidget(self.zoom_out_btn)self.v_layout.addLayout(self.h_layout)self.v_layout.addWidget(self.browser)self.setLayout(self.v_layout)def browser_init(self):self.browser.load(QUrl('https://baidu.com'))self.browser.urlChanged.connect(lambda: self.url_le.setText(self.browser.url().toDisplayString()))def btn_init(self):self.back_btn.setIcon(QIcon('images/back.png'))self.forward_btn.setIcon(QIcon('images/forward.png'))self.refresh_btn.setIcon(QIcon('images/refresh.png'))self.zoom_in_btn.setIcon(QIcon('images/zoom_in.png'))self.zoom_out_btn.setIcon(QIcon('images/zoom_out.png'))self.back_btn.clicked.connect(self.browser.back)self.forward_btn.clicked.connect(self.browser.forward)self.refresh_btn.clicked.connect(self.browser.reload)self.zoom_in_btn.clicked.connect(self.zoom_in_func)self.zoom_out_btn.clicked.connect(self.zoom_out_func)def le_init(self):self.url_le.setFixedWidth(400)self.url_le.setPlaceholderText('Search or enter website name')def keyPressEvent(self, QKeyEvent):if QKeyEvent.key() == Qt.Key_Return or QKeyEvent.key() == Qt.Key_Enter:if self.url_le.hasFocus():if self.url_le.text().startswith('https://') or self.url_le.text().startswith('http://'):self.browser.load(QUrl(self.url_le.text()))else:self.browser.load(QUrl('https://'+self.url_le.text()))def zoom_in_func(self):self.browser.setZoomFactor(self.browser.zoomFactor()+0.1)def zoom_out_func(self):self.browser.setZoomFactor(self.browser.zoomFactor()-0.1)if __name__ == '__main__':app = QApplication(sys.argv)demo = Demo()demo.show()sys.exit(app.exec_())

30.2 小结

1. 这个简单的浏览器还可以添加很多功能,或者再进行完善,让它更像一个真正的浏览器。比如程序首次运行时,前进和后退按钮应该都要设置为不可用,而且在无法前进和后退是也要设置为不可用(涉及到history()方法,小伙伴可以自己去实现下)。

2. 还是那句话——多查文档。如果你脑海里有想要实现的功能,你可以去查下文档看看这个控件有没有提供相应的方法。或者你脑海里可能一片空白,那你其实也可以先去读下文档看看某控件提供方法有没有你喜欢的,能给你带来灵感也说不定。

.net网页input 赋值 提交时空白_《快速掌握PyQt5》第三十章 网页交互QWebEngineView...相关推荐

  1. Vue form表单input框 手动赋值 提交时 表单input值没有生效 验证仍然是空

    一.问题 1.input 赋值后表单提交却为空 在调用接口将返回的值赋在表单的 input 上或者子页面传递数值给父页面form表单model元素后,提交表单,明明值已经赋上去了,结果提交后显示的该值 ...

  2. mybatis 批量提交清除缓存_重学Mybatis(三)-------缓存 (含面试题)

    博主将会针对Java面试题写一组文章,包括J2ee,SQL,主流Web框架,中间件等面试过程中面试官经常问的问题,欢迎大家关注.一起学习,一起成长,文章底部有面试题. mybatis的一级缓存 myb ...

  3. hikvision v2.3控件网页demo_《快速掌握PyQt5》第三十章 网页交互QWebEngineView

    如果需要在程序中加载并显示网页,那QWebEngineView绝对是最佳的选择.该控件基于Chrome浏览器内核引擎,所提供的功能和方法还是比较强大的. 注:V5.11及更高版本的PyQt5中不包含Q ...

  4. 学pyqt5之前需要学python吗_快速学习pyqt5(1)--入门

    学习于:PyQt5图形界面编程 想要系统学习的同学建议可以去这个专栏好好学习,没有任何语言基础和计算机基础的也建议直接去看那个专栏.我这里是有java基础了,所以就不重复,针对快速学习使用. 学习这个 ...

  5. 如何在html的form提交时排除某些input field的内容

    在Html的form点击提交时,form内所有Input filed的内容,只要是有name属性的,并且没有disabled属性的,都会被提交,即通过网络发送到指定的URL. 如:下面的html代码显 ...

  6. 织梦DEDECMS网站留言板提交时验证码错误返回空白页的解决办法

    织梦DEDECMS模板网站留言板提交时验证码错误返回空白页的解决办法: 默认情况下,如果我们使用DEDE模板中的默认留言板时,如果留言信息不正确或者输入内容为空时,dedecms系统就会返回一个空白页 ...

  7. number——input新属性,提交时自动检测数字格式,大小

    提交时自动检测数字格式,大小: 可编辑手动输入,也可以点击上下键调节大小 <!DOCTYPE html> <html><head><meta charset= ...

  8. 提交时是使用防抖还是节流_使用BlockingExecutor进行节流任务提交

    提交时是使用防抖还是节流 JDK的java.util.concurrent.ThreadPoolExecutor允许您将任务提交到线程池,并使用BlockingQueue来保存提交的任务. 如果要提交 ...

  9. input赋值时的空格问题

    很多情况下我们都会涉及到给input赋值的情况,大部分情况下都会很随意自由的用下面如图所示的方法: 但是这样大部分情况下是对的,但是当数据里面包含空格的时候,例如:就会出现"错误" ...

最新文章

  1. 英特尔在网络营销之下即将出现大动作,第二季度服务器出货率将有所提升
  2. python利用集合的无重复性_利用Python程序完成ABAQUS中的一些重复性操作
  3. Kettle 简介和实例
  4. linux自学第二天
  5. Eviews建立Var模型1
  6. 开源Java(JSP) CMS系统源码推荐
  7. SPSS两独立样本t检验
  8. 图片转Word文档怎么转
  9. SAP中常用SM系列事务代码总结
  10. google 新功能 快讯
  11. 小程序加载不出来图片
  12. Barefoot Networks进军白盒市场
  13. 带宽、延时、吞吐率、PPS 这些都是啥?
  14. FPGA EMMC HS400模式verilog驱动开发
  15. 在金融科技的诸多技术领域,目前最引人瞩目的当属区块链
  16. unity入门2.0
  17. 【华为云计算产品系列】FusionCompute虚拟化
  18. 闲人闲谈PS之一项目库存跨公司业务STO解决方案--SAP闲人的开篇
  19. 一个简单的BitTorrent客户端实现(二):种子文件解析及信息保存
  20. 城中村、小区WiFi覆盖方案

热门文章

  1. 资源放送丨《Oracle数据库SQL执行计划的取得和解析》PPT视频
  2. SQL查询提速秘诀,避免锁死数据库的数据库代码
  3. 组合式应用新利器?SaaS新时代事件网格如何解决集成标准化问题
  4. 10个问题让你快速避开java中的jdbc常见坑
  5. Java的这个强大功能,很多人都不知道
  6. 13万张表+数亿行代码,迁移只需数小时,还是异构数据库
  7. 6大创新技术及2亿美元投入计划,这个活动有点料
  8. java mongodb 多文档_如何通过Java在MongoDB中一次性插入多个文档
  9. Django UnicodeEncodeError解决
  10. 枚举函数enumerate