首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >python3GUI--模仿Chrome浏览器 By:PyQt5(支持视频播放)

python3GUI--模仿Chrome浏览器 By:PyQt5(支持视频播放)

原创
作者头像
懷淰
发布2025-11-19 20:07:40
发布2025-11-19 20:07:40
3260
举报
文章被收录于专栏:PyQt5PyQt5

本博客将详细讲解一个支持视频播放的多功能PyQt5浏览器的开发实现过程

视频演示地址:PyQt5实现Chrome-功能演示

一.前言

朋友们好啊,本次给大家带来我开发的模仿Chrome的一款浏览器,记得在2021年博主开发过一款浏览器-python3GUI--浏览器By:PyQt5,当时的界面效果粗糙,页面耦合性低,并且无法播放h5视频,本次给大家详细介绍我新开发的这款浏览器,为各位道友提供开发思路。

二.项目简介

博主使用一张思维导图展示所有功能,大家可以自行放大查看。

三.详细模块介绍

1.主界面

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

2.书签管理页面

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

2.历史记录管理页面

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

3.下载内容管理页面

此页面将按照日期分组展示所有位于“下载目录”的文件,支持搜索下载记录,除了基本的信息展示,还支持文件操作;在文件夹中打开、删除移动到回收站,用户可以在这个页面统一管理所有的下载内容。

四.理论基础

1.用到的核心类

这里介绍一下在浏览器开发过程中用到的QtWebEngine相关类,以及我们对这些类实现了哪些具体的功能,给大家一个参考。

QtWebEngine的继承关系见下图:

1.QWebEngineView

QWebEngineView 是 Qt 提供的基于 Chromium 内核的网页渲染控件,用于在桌面应用中嵌入完整的浏览器能力。它能够加载和展示网页、执行 JavaScript、处理页面导航、下载、Cookies、History 等浏览器行为,并允许开发者通过扩展 QWebEngineProfile、QWebEnginePage 以及事件重写实现更丰富的功能,如拦截请求、自定义右键菜单、交互桥接、开发者工具等。对于需要在应用中内嵌网页、实现混合界面或构建轻量浏览器的场景,它是 Qt WebEngine 模块的核心组件。

我们自己定义了一个类CustomWebEngineView 继承自QWebEngineView,实现了一些个性化配置与功能,具体的功能包括:

初始化与配置

  1. 使用独立的 WebEngineProfile,实现缓存与 Cookie 的完全隔离
  2. 启用 JavaScript、图片加载、插件支持、全屏等常用浏览功能
  3. 全局字体统一设置为“微软雅黑”
  4. 页面加载基于自定义的 CustomWebEnginePage

页面信息管理

  1. 自动获取并记录网页标题
  2. 自动提取并记录 favicon 地址并写入数据库
  3. 提供包含标题、图标、URL、前进后退状态、缩放比例等信息的完整页面字典
  4. 自动判断当前浏览上下文对应的 UA 类型(PC、Android、iOS)

UA 切换

  1. 通过名称切换预设的 User-Agent
  2. 切换后立即刷新页面使 UA 生效

下载相关功能

  1. 拦截 DownloadRequested 事件以控制网页下载行为
  2. 在下载开始、完成、中断时弹窗提示
  3. 自动将文件保存到默认下载目录
  4. 支持手动输入 URL 进行下载,并可根据内容类型给出文件名建议
  5. 针对图片类型提供独立的下载逻辑

查看与保存网页源代码

  1. 在新标签中打开当前页面源代码,并使用临时 HTML 文件展示
  2. 将当前页面的 HTML 内容保存到本地文件

图片相关功能

  1. 右键菜单提供图片另存为
  2. 支持复制图片链接
  3. 可在新窗口打开图片

查找功能

  1. 查找栏提供输入框、上下查找按钮和关闭按钮
  2. 支持高亮所有匹配项
  3. 可跳转到上一条或下一条匹配
  4. 支持清除全部高亮

自定义右键菜单

  1. 文本输入框:剪切、复制、粘贴、全选
  2. 图片区域:保存图片、打开图片、复制图片链接
  3. 普通区域:后退、前进、刷新、复制链接
  4. 提供开发者工具入口,用于检查元素
  5. 可查看网页源代码

布局与界面调整

  1. 查找栏会自动定位于界面右上角,避免出现界面越界
  2. 提示条自动显示在底部位置
  3. 在窗口大小变化时自动调整相关 UI 组件布局

2.QWebEnginePage

QWebEnginePage 是 PyQt5 中用于承载和控制网页内容的核心类,它负责处理页面的加载、导航、渲染以及与 JavaScript 的交互,同时管理网页行为(如弹窗、导航请求、文件下载、权限请求等)。它常作为 QWebEngineView 的底层页面对象存在,可通过继承它来自定义浏览器逻辑,例如控制 User-Agent、处理右键菜单、拦截链接跳转、修改页面事件处理方式等,是构建自定义浏览器功能时最关键的组件之一。

我们定义了一个类CustomWebEnginePage,实现了以下的功能:

  1. 通过保存主窗口引用,让页面能够与外部浏览器结构进行协作,实现标签页管理与页面调度。
  2. 覆写 createWindow,使所有新窗口请求由主窗口统一处理,并在需要时创建新标签并返回相应的页面对象,从而实现自定义的新页面打开方式。
  3. 在 certificateError 中输出证书错误的类型与相关 URL,便于调试和安全问题排查,同时保持对异常证书的拒绝。
  4. 在 acceptNavigationRequest 中拦截用户点击的链接,采用自定义逻辑加载目标 URL,并阻止默认跳转行为,实现对导航流程的主动控制与可扩展性。

3.QWebEngineProfile

QWebEngineProfile 是用于管理浏览器上下文的核心组件,它负责处理缓存、Cookie、存储数据、权限设置、下载行为以及持久化策略等内容。同一个 profile 代表一个独立的浏览环境,多个 WebEngineView 或 WebEnginePage 可以共享同一个 profile,从而共享登录状态、缓存和配置;也可以创建独立的 profile 来实现隐私模式、隔离存储、独立会话等需求。通过它可以配置 User-Agent、自定义存储路径、启用或禁用持久化、管理 cookie 存取,并能监听下载、权限请求等事件,是构建多标签浏览器、隐私浏览模式或多用户隔离环境时的重要基础。

我们并没有重写这个类,而是直接使用的其中的方法:

首先,通过使用带时间戳的名称创建一个新的 QWebEngineProfile,实现与其他页面完全隔离的浏览上下文,使缓存、Cookie、存储目录不会与已有配置混用。接着将缓存模式设置为磁盘缓存,使网页资源能够持久存储在本地以加快后续加载速度。最后指定 Cookie 策略为允许持久化,让网站设置的 Cookie 能在浏览器退出后继续保存,从而保持登录状态和站点偏好等信息。

4.QWebEngineSettings

QWebEngineSettings 用于控制网页渲染与浏览行为的各项特性,是 WebEngine 的全局或单页面级配置入口。通过它可以开启或关闭诸如 JavaScript、图片加载、插件、全屏支持、网页缩放、自定义字体、自动播放媒体、跨域访问、开发者工具等功能。它既能为所有页面设置统一策略,也能针对某个页面进行独立配置,从而灵活决定网页在浏览器中的表现方式,是调节浏览体验、性能与安全策略的重要组件。

我们通过调用QWebEngineSettings完成了两个方面的配置:网页功能开启与字体设置。

  • 启用插件支持(PluginsEnabled),保证某些网页内容如 Flash 或浏览器插件可以运行。
  • 自动加载图片(AutoLoadImages),使网页显示完整视觉内容。
  • 启用 JavaScript(JavascriptEnabled),保证网页交互脚本正常执行。
  • 支持全屏(FullScreenSupportEnabled),允许网页进入全屏模式。
  • 允许媒体播放无需用户手势(PlaybackRequiresUserGesture=False),自动播放视频或音频。
  • 禁止页面导航自动获得焦点(FocusOnNavigationEnabled=False),避免页面切换打断用户操作。
  • 禁用屏幕捕获(ScreenCaptureEnabled=False)、硬件加速 2D 画布(Accelerated2dCanvasEnabled=False)和 WebGL(WebGLEnabled=False),提升安全性或减少性能开销。
  • 禁用错误页面显示(ErrorPageEnabled=False),避免默认错误页面弹出。5.QWebEngineDownloadItem

QWebEngineDownloadItem 是 PyQt5 中用于管理和控制网页下载任务的类,它封装了下载文件的整个生命周期,包括下载开始、进度更新、暂停、恢复、取消以及完成等事件。通过它可以获取下载文件的 URL、保存路径、文件名、总大小和当前已下载大小,同时可以设置自动保存路径或自定义下载逻辑,还能监听下载状态变化,用于在界面上显示进度、弹窗提示或处理下载异常,是实现浏览器下载管理功能的核心工具。

在我们的代码中实现了浏览器中网页文件的统一下载管理逻辑。on_download_requested 用于处理 QWebEngineDownloadItem 发起的下载请求,首先判断下载是否为新请求,避免重复处理,然后将文件保存到默认下载目录,并在下载开始时弹窗提示用户。下载完成后,根据状态显示不同提示,包括完成、取消或中断,同时使用 finished 信号绑定回调处理结束状态。handle_download 方法提供一个统一的下载接口,无论是通过 QWebEngineDownloadItem 还是直接 URL,都能将文件保存到默认目录。如果是 QWebEngineDownloadItem,则设置路径并接受下载,同时绑定完成提示;如果直接通过 URL 下载,则使用 requests 获取文件流并写入本地,同时处理异常并反馈下载失败信息,从而实现自动、统一、可提示的下载管理功能。

五.核心问题回答

1.软件系统UI布局

软件主要由下面四个区域构成整体是垂直布局,内部的顶部是顶部标题区域,下方是一个堆栈组件,堆栈组件内部第一页是核心内容区域,这个区域包含顶部地址区域、书签区域、核心网页内容展示区域,和“核心内容区域”并列的堆栈页面子页面分别是:下载内容管理页、书签管理页、历史数据管理页,软件布局不是很复杂,也没有用上复杂的布局主要就是水平布局和垂直布局,可以用一句顺口溜:整体垂直,内部水平,组件和布局属于是PyQt5开发的基础了,大家看了我这么多博客了,应该是有一些基础了。

本次软件系统没有使用qt设计师设计UI,仍然采用的是手搓组件,采用自定义的组件类来实现每一个具体的功能,保证了整体系统的一致性与统一,对于敏捷开发来说很是方便!

2.如何实现视频播放?

要想知道如何实现视频播放,就得先知道为什么原生的QWebEngine不能播放视频

PyQt5 的 QWebEngineView 无法正常播放网页视频,主要由于其内置的 QtWebEngine 基于精简版 Chromium,默认移除了 H.264、AAC 等受专利限制的常用视频解码器,而大多数网页与 MP4 视频都依赖这些编码格式;同时部分媒体功能、DRM 支持和硬件加速路径也被裁剪,因此在未额外补充完整 ffmpeg 或使用更新的 Qt6 版本之前,网页视频通常会无法播放或出现黑屏。

我们是这样实现网页视频播放的:

采用重新编译的QtWebEngine,并在编译时启用 proprietary codecs,同时结合自带或外置的完整 ffmpeg,使其具备完整的媒体解码链路,这样网页上的视频就能播放了,整个编译过程很耗时,取决于机器,性能较好的机器估计也需要几十个小时或者一天的时间。

3.标签是如何自定义实现的?

我们定义了自定义的QTabBar组件类,实现了tab右击菜单、关闭按钮、添加按钮的展示,我们的自定义QTabBar实现了以下功能:

  • 可关闭和可拖动标签:标签页自带关闭按钮,并支持拖动调整顺序。
  • “+”按钮新建标签:标签栏右侧有一个按钮,用于创建新标签页,位置会随标签数量和窗口大小动态调整。
  • 动态标签宽度:标签宽度会根据总数量和窗口宽度自动缩放,同时保持最大最小限制。
  • 右键菜单操作:支持右键菜单,可以复制标签名、重新加载、关闭当前、关闭其他或关闭左右标签页,菜单选项会根据标签数量动态启用或禁用。
  • 双击操作:双击空白处可以新建标签,双击已有标签仍保留默认行为。
  • 信号化设计:通过自定义信号 tab_close_requested 通知外部标签关闭事件,便于外部逻辑处理。 实现的具体效果见下图啦:

4.全局快捷键

博主使用一张表格展示所有快捷键与功能

按键组合

功能描述

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

前进

5.信号总线

项目中难以避免的就是数据流转,这直接影响我们的系统逻辑代码撰写,这里我们为了解耦,定义了一个信号总线类,并且实例化供不同类之间调用,在数据产生的位置发射信号,在使用数据的位置接收处理信号,信号和槽的关系一直贯穿在我们的系统之中,通过定义信号总线,避免了处理多层信号的发射与连接,让我们的系统代码更加清楚,下面是我们系统中用到的信号总线:

6.资源处理

本系统使用qrc作为系统资源,通过维护一份resource.qrc文件来维护整个系统的资源数据,所有的资源数据都放到了resource目录下,通过不同的文件夹(qrc前缀)来区分不同资源文件的用途,这里有的朋友可能会问:那每次删减了资源数据,是不是都需要重新生成资源数据呢?那肯定是的,一般来说需要使用pyrcc将.qrc转成.py,至少也需要两步,这里我们为了简化中间操作步骤,撰写了一个脚本,可以帮我们自动处理资源文件数据,给大家贴出来:

代码语言:python
复制
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资源数据

7.关于项目

我们的项目为私有项目,项目名称为pyqt5-smart-broswer,项目开发周期约为一个月,主要耗时的地方是样式设计,好在问题都解决了。

1.项目结构

我们的项目核心源代码位于src/目录下,通过不同的包之间的调度串联起整个的系统,系统以main.py为入口,启动整个项目。

2.项目依赖

本项目依赖很简单,主要是PyQt5和PyQtWebEngine,整个项目的依赖我贴在下面了

代码语言:bash
复制
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

大家可以执行下面的命令一键安装项目依赖

代码语言:bash
复制
pip install -r requirements.txt

3.项目打包

本项目在windows11电脑上使用PyCharm开发,使用PyInstaller打包,最后使用Inno Setup 编译器制作成了安装包,安装包名字定义为:MyChrome.exe,由于相关依赖进行了重新编译,所以这个安装包有点大,约为640M。本次就不给大家分享安装包了。

六.总结

本次给大家介绍了我使用PyQt5开发的浏览器系统,真的就是系统,在开发过程中博主没有把他当做是一个demo去撰写,而是当做是一个完整的系统去开发,这个系统不仅支持了网页浏览、tab管理基本的需求,还支持了历史记录、书签管理、登录系统等常用的相关功能模块,所有子页面功能都和模块一样即插即用,软件系统的相关组件类互相依赖实现了高内聚,低耦合的完整软件系统!

PS:需要代码的同学可以加我的WX,就在博客下方,通过付费的方式可以得到:

1、完整的软件系统代码

2、配套的xmind思维导图原始文件

3、免费远程部署

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.前言
  • 二.项目简介
  • 三.详细模块介绍
    • 1.主界面
    • 2.书签管理页面
    • 2.历史记录管理页面
    • 3.下载内容管理页面
  • 四.理论基础
    • 1.用到的核心类
      • 1.QWebEngineView
      • 2.QWebEnginePage
      • 3.QWebEngineProfile
      • 4.QWebEngineSettings
  • 五.核心问题回答
    • 1.软件系统UI布局
    • 2.如何实现视频播放?
    • 3.标签是如何自定义实现的?
    • 4.全局快捷键
    • 5.信号总线
    • 6.资源处理
    • 7.关于项目
      • 1.项目结构
      • 2.项目依赖
      • 3.项目打包
  • 六.总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档