
本博客将详细讲解一个支持视频播放的多功能PyQt5浏览器的开发实现过程
视频演示地址:PyQt5实现Chrome-功能演示
朋友们好啊,本次给大家带来我开发的模仿Chrome的一款浏览器,记得在2021年博主开发过一款浏览器-python3GUI--浏览器By:PyQt5,当时的界面效果粗糙,页面耦合性低,并且无法播放h5视频,本次给大家详细介绍我新开发的这款浏览器,为各位道友提供开发思路。
博主使用一张思维导图展示所有功能,大家可以自行放大查看。

软件启动后直接打开主界面,用户在不登录的时候也是可以使用浏览器的,并且支持历史浏览数据记录,我们为用户设计了个性化的主页面,主界面支持编辑搜索以及历史浏览网址的查看,按照用户最后浏览时间降序展示前8个浏览记录,使用半透明的效果展示网址内容,使用圆形+网站第一个字母文字的方式让用户直观地查看网址信息。用户可以在上面输入关键字后点击“搜索”按钮或者按下回车键调用百度进行搜索。

在这个页面登录的用户可以对自己收藏的书签网址进行管理,具体的操作有:点击打开书签内容,通过菜单删除书签、当前页面打开书签、新页面打开书签、复制书签url地址到剪切板,这些操作很常用。

在这个页面用户可以管理自己的浏览历史记录,通过关键字搜索历史浏览网站,此页面按照浏览日期分组,内部按照日期降序排序,用户可以直接点击链接跳转到目标网址,也可以通过点击菜单对网址进行删除、复制、打开,也支持用户清空所有浏览历史记录,操作习惯符合用户常用的浏览器的操作。

此页面将按照日期分组展示所有位于“下载目录”的文件,支持搜索下载记录,除了基本的信息展示,还支持文件操作;在文件夹中打开、删除移动到回收站,用户可以在这个页面统一管理所有的下载内容。
这里介绍一下在浏览器开发过程中用到的QtWebEngine相关类,以及我们对这些类实现了哪些具体的功能,给大家一个参考。
QtWebEngine的继承关系见下图:

QWebEngineView 是 Qt 提供的基于 Chromium 内核的网页渲染控件,用于在桌面应用中嵌入完整的浏览器能力。它能够加载和展示网页、执行 JavaScript、处理页面导航、下载、Cookies、History 等浏览器行为,并允许开发者通过扩展 QWebEngineProfile、QWebEnginePage 以及事件重写实现更丰富的功能,如拦截请求、自定义右键菜单、交互桥接、开发者工具等。对于需要在应用中内嵌网页、实现混合界面或构建轻量浏览器的场景,它是 Qt WebEngine 模块的核心组件。
我们自己定义了一个类CustomWebEngineView 继承自QWebEngineView,实现了一些个性化配置与功能,具体的功能包括:
初始化与配置
页面信息管理
UA 切换
下载相关功能
查看与保存网页源代码
图片相关功能
查找功能
自定义右键菜单
布局与界面调整
QWebEnginePage 是 PyQt5 中用于承载和控制网页内容的核心类,它负责处理页面的加载、导航、渲染以及与 JavaScript 的交互,同时管理网页行为(如弹窗、导航请求、文件下载、权限请求等)。它常作为 QWebEngineView 的底层页面对象存在,可通过继承它来自定义浏览器逻辑,例如控制 User-Agent、处理右键菜单、拦截链接跳转、修改页面事件处理方式等,是构建自定义浏览器功能时最关键的组件之一。
我们定义了一个类CustomWebEnginePage,实现了以下的功能:
QWebEngineProfile 是用于管理浏览器上下文的核心组件,它负责处理缓存、Cookie、存储数据、权限设置、下载行为以及持久化策略等内容。同一个 profile 代表一个独立的浏览环境,多个 WebEngineView 或 WebEnginePage 可以共享同一个 profile,从而共享登录状态、缓存和配置;也可以创建独立的 profile 来实现隐私模式、隔离存储、独立会话等需求。通过它可以配置 User-Agent、自定义存储路径、启用或禁用持久化、管理 cookie 存取,并能监听下载、权限请求等事件,是构建多标签浏览器、隐私浏览模式或多用户隔离环境时的重要基础。
我们并没有重写这个类,而是直接使用的其中的方法:
首先,通过使用带时间戳的名称创建一个新的 QWebEngineProfile,实现与其他页面完全隔离的浏览上下文,使缓存、Cookie、存储目录不会与已有配置混用。接着将缓存模式设置为磁盘缓存,使网页资源能够持久存储在本地以加快后续加载速度。最后指定 Cookie 策略为允许持久化,让网站设置的 Cookie 能在浏览器退出后继续保存,从而保持登录状态和站点偏好等信息。
QWebEngineSettings 用于控制网页渲染与浏览行为的各项特性,是 WebEngine 的全局或单页面级配置入口。通过它可以开启或关闭诸如 JavaScript、图片加载、插件、全屏支持、网页缩放、自定义字体、自动播放媒体、跨域访问、开发者工具等功能。它既能为所有页面设置统一策略,也能针对某个页面进行独立配置,从而灵活决定网页在浏览器中的表现方式,是调节浏览体验、性能与安全策略的重要组件。
我们通过调用QWebEngineSettings完成了两个方面的配置:网页功能开启与字体设置。
QWebEngineDownloadItem 是 PyQt5 中用于管理和控制网页下载任务的类,它封装了下载文件的整个生命周期,包括下载开始、进度更新、暂停、恢复、取消以及完成等事件。通过它可以获取下载文件的 URL、保存路径、文件名、总大小和当前已下载大小,同时可以设置自动保存路径或自定义下载逻辑,还能监听下载状态变化,用于在界面上显示进度、弹窗提示或处理下载异常,是实现浏览器下载管理功能的核心工具。
在我们的代码中实现了浏览器中网页文件的统一下载管理逻辑。on_download_requested 用于处理 QWebEngineDownloadItem 发起的下载请求,首先判断下载是否为新请求,避免重复处理,然后将文件保存到默认下载目录,并在下载开始时弹窗提示用户。下载完成后,根据状态显示不同提示,包括完成、取消或中断,同时使用 finished 信号绑定回调处理结束状态。handle_download 方法提供一个统一的下载接口,无论是通过 QWebEngineDownloadItem 还是直接 URL,都能将文件保存到默认目录。如果是 QWebEngineDownloadItem,则设置路径并接受下载,同时绑定完成提示;如果直接通过 URL 下载,则使用 requests 获取文件流并写入本地,同时处理异常并反馈下载失败信息,从而实现自动、统一、可提示的下载管理功能。
软件主要由下面四个区域构成整体是垂直布局,内部的顶部是顶部标题区域,下方是一个堆栈组件,堆栈组件内部第一页是核心内容区域,这个区域包含顶部地址区域、书签区域、核心网页内容展示区域,和“核心内容区域”并列的堆栈页面子页面分别是:下载内容管理页、书签管理页、历史数据管理页,软件布局不是很复杂,也没有用上复杂的布局主要就是水平布局和垂直布局,可以用一句顺口溜:整体垂直,内部水平,组件和布局属于是PyQt5开发的基础了,大家看了我这么多博客了,应该是有一些基础了。
本次软件系统没有使用qt设计师设计UI,仍然采用的是手搓组件,采用自定义的组件类来实现每一个具体的功能,保证了整体系统的一致性与统一,对于敏捷开发来说很是方便!

要想知道如何实现视频播放,就得先知道为什么原生的QWebEngine不能播放视频
PyQt5 的 QWebEngineView 无法正常播放网页视频,主要由于其内置的 QtWebEngine 基于精简版 Chromium,默认移除了 H.264、AAC 等受专利限制的常用视频解码器,而大多数网页与 MP4 视频都依赖这些编码格式;同时部分媒体功能、DRM 支持和硬件加速路径也被裁剪,因此在未额外补充完整 ffmpeg 或使用更新的 Qt6 版本之前,网页视频通常会无法播放或出现黑屏。
我们是这样实现网页视频播放的:
采用重新编译的QtWebEngine,并在编译时启用 proprietary codecs,同时结合自带或外置的完整 ffmpeg,使其具备完整的媒体解码链路,这样网页上的视频就能播放了,整个编译过程很耗时,取决于机器,性能较好的机器估计也需要几十个小时或者一天的时间。

我们定义了自定义的QTabBar组件类,实现了tab右击菜单、关闭按钮、添加按钮的展示,我们的自定义QTabBar实现了以下功能:
tab_close_requested 通知外部标签关闭事件,便于外部逻辑处理。
实现的具体效果见下图啦:
博主使用一张表格展示所有快捷键与功能
按键组合 | 功能描述 |
|---|---|
Ctrl + T | 新建标签页 |
Ctrl + Y | 打开历史记录 |
Ctrl + L | 打开下载页面 |
Ctrl + B | 打开书签管理器 |
Ctrl + F | 页面查找(显示查找条) |
Ctrl + H | 打开帮助 |
Ctrl + K | 打开设置页 |
Ctrl + D | 当前页面加入收藏 |
Esc | 关闭查找条 |
F12 | 打开开发者工具 |
Ctrl + W | 关闭当前标签页 |
Ctrl + R | 刷新当前页面 |
Ctrl + J | 执行 JS 注入 |
Alt + ← | 后退 |
Alt + → | 前进 |
Ctrl + Shift + Tab | 切换到前一个标签页 |
Ctrl + Tab | 切换到下一个标签页 |
Alt + Home | 打开主页 |
F11 | 全屏 / 退出全屏 |
Ctrl + 0 | 还原缩放 |
F5 | 刷新当前页面(同 Ctrl+R) |
Ctrl + M | 打开 Tab 管理器 |
Ctrl + S | 保存网页源代码 |
鼠标侧键 XButton1 | 后退 |
鼠标侧键 XButton2 | 前进 |
项目中难以避免的就是数据流转,这直接影响我们的系统逻辑代码撰写,这里我们为了解耦,定义了一个信号总线类,并且实例化供不同类之间调用,在数据产生的位置发射信号,在使用数据的位置接收处理信号,信号和槽的关系一直贯穿在我们的系统之中,通过定义信号总线,避免了处理多层信号的发射与连接,让我们的系统代码更加清楚,下面是我们系统中用到的信号总线:

本系统使用qrc作为系统资源,通过维护一份resource.qrc文件来维护整个系统的资源数据,所有的资源数据都放到了resource目录下,通过不同的文件夹(qrc前缀)来区分不同资源文件的用途,这里有的朋友可能会问:那每次删减了资源数据,是不是都需要重新生成资源数据呢?那肯定是的,一般来说需要使用pyrcc将.qrc转成.py,至少也需要两步,这里我们为了简化中间操作步骤,撰写了一个脚本,可以帮我们自动处理资源文件数据,给大家贴出来:
import os
import subprocess
def generate_qrc_content(root_dir):
files = [
"<file>{}</file>".format(os.path.relpath(os.path.join(root, file), root_dir).replace('\\', '/'))
for root, _, files in os.walk(root_dir)
for file in files
if
".qrc" not in file and ".py" not in file
]
return "<RCC>\n <qresource>\n" + "\n".join(
" {}".format(file) for file in files) + "\n </qresource>\n</RCC>"
def generate_qrc_file(qrc_file_path, content):
with open(qrc_file_path, 'w') as qrc_file:
qrc_file.write(content)
def compile_qrc_to_py(qrc_file_path):
py_file_path = qrc_file_path.replace('.qrc', '_rc.py')
subprocess.run(['pyrcc5', qrc_file_path, '-o', py_file_path], check=True)
def main():
root_dir = "../src/resource/"
qrc_file_path = root_dir + "/resource.qrc"
qrc_content = generate_qrc_content(root_dir)
generate_qrc_file(qrc_file_path, qrc_content)
compile_qrc_to_py(qrc_file_path)
if __name__ == "__main__":
main()具体来说就是:调用oyrcc5环境来读取指定目录下的资源数据先生成.qrc文件然后生成.py资源数据
我们的项目为私有项目,项目名称为pyqt5-smart-broswer,项目开发周期约为一个月,主要耗时的地方是样式设计,好在问题都解决了。
我们的项目核心源代码位于src/目录下,通过不同的包之间的调度串联起整个的系统,系统以main.py为入口,启动整个项目。

本项目依赖很简单,主要是PyQt5和PyQtWebEngine,整个项目的依赖我贴在下面了
PyQt5==5.15.11
PyQt5_sip==12.15.0
PyYAML==6.0.2
PyYAML==6.0.3
QtAwesome==1.3.1
Requests==2.32.5
Send2Trash==1.8.0
PyQtWebEngine==5.15.5大家可以执行下面的命令一键安装项目依赖
pip install -r requirements.txt本项目在windows11电脑上使用PyCharm开发,使用PyInstaller打包,最后使用Inno Setup 编译器制作成了安装包,安装包名字定义为:MyChrome.exe,由于相关依赖进行了重新编译,所以这个安装包有点大,约为640M。本次就不给大家分享安装包了。

本次给大家介绍了我使用PyQt5开发的浏览器系统,真的就是系统,在开发过程中博主没有把他当做是一个demo去撰写,而是当做是一个完整的系统去开发,这个系统不仅支持了网页浏览、tab管理基本的需求,还支持了历史记录、书签管理、登录系统等常用的相关功能模块,所有子页面功能都和模块一样即插即用,软件系统的相关组件类互相依赖实现了高内聚,低耦合的完整软件系统!
PS:需要代码的同学可以加我的WX,就在博客下方,通过付费的方式可以得到:
1、完整的软件系统代码
2、配套的xmind思维导图原始文件
3、免费远程部署

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。