基于pyQT5的简单浏览器的制作
需求分析
我们先了解一下浏览器的运行机制和设计模块
1.我们首先要知道浏览器有几个模块然后根据模块进行设计
- 浏览器进程:复制浏览器的功能实现比如浏览器的前进、后退、地址栏、书签栏的工作,处理一些浏览器的网络请求
- 渲染进程:一个浏览器的显示功能比如html和css的渲染功能
- 插件进程:负责处理一个浏览器的插件处理
- GPU进程:负责处理一个浏览器的gpu渲染任务
2.然后我们对浏览器的运行机制进行了解
- 浏览器通过我们输入的url进行解析这里我们拿百度的网址做一个示例,www.baidu.com,我们的浏览器通过根域名服务器进行寻址然后进行com顶级域名寻址然后对baidu.com进行寻址然后对www.baidu.com进行数据请求
- 当我们的数据请求到服务器的之后服务器就会返回数据这个过程相当于http协议->tcp->三次握手传输数据->返回http响应的报文,数据被浏览器接收
- 当我们的浏览器接收到http响应之后会有数据进行传输,这个时候的数据变成来字节码,我们的浏览器对字节码进行解析然后就可以得到浏览器的显示界面
浏览器的源码设计
对于浏览器的内核设计,以我们现在的水平是不够进行编写的因为有很多的底层代码和编解码,所以我们采用py中的QtWebEngineWidgets浏览器引擎进行为我们代替这些底层代码.
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *
import sys
class WebView(QWebEngineView):
def __init__(self, parent):
super().__init__(parent)
def createWindow(self, webWindowType):
return main_demo.browser
class MainDemo(QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setWindowTitle('Txh浏览器')
self.setWindowIcon(QIcon('icons/penguin.png'))
self.resize(1600, 1520)
self.show()
# 添加URL地址栏
self.urlbar = QLineEdit()
# 让地址栏支持输入地址回车访问
self.urlbar.returnPressed.connect(self.navigate_to_url)
# 添加标签栏
self.tabs = QTabWidget()
self.tabs.setDocumentMode(True)
self.tabs.tabBarDoubleClicked.connect(self.tab_open)
self.tabs.currentChanged.connect(self.current_tab_changed)
# 允许关闭标签
self.tabs.setTabsClosable(True)
# 设置关闭按钮的槽
self.tabs.tabCloseRequested.connect(self.close_current_tab)
self.add_new_tab(QUrl('https://www.baidu.com/'), '百度一下,你就知道')
self.setCentralWidget(self.tabs)
new_tab_action = QAction(QIcon('icons/add_page.png'), 'New Page', self)
new_tab_action.triggered.connect(self.add_new_tab)
# 添加导航栏
navigation_bar = QToolBar('Navigation')
# 设定图标大小
navigation_bar.setIconSize(QSize(24, 24))
self.addToolBar(navigation_bar)
# 添加前进、后退、停止加载和刷新的按钮
back_button = QAction(QIcon('icons/back.png'), 'Back', self)
forward_button = QAction(QIcon('icons/forward.png'), 'Forward', self)
stop_button = QAction(QIcon('icons/stop.png'), 'Stop', self)
reload_button = QAction(QIcon('icons/renew.png'), 'Reload', self)
back_button.triggered.connect(self.tabs.currentWidget().back)
forward_button.triggered.connect(self.tabs.currentWidget().forward)
stop_button.triggered.connect(self.tabs.currentWidget().stop)
reload_button.triggered.connect(self.tabs.currentWidget().reload)
# 将按钮添加到导航栏上
navigation_bar.addAction(back_button)
navigation_bar.addAction(forward_button)
navigation_bar.addAction(stop_button)
navigation_bar.addAction(reload_button)
navigation_bar.addSeparator()
navigation_bar.addWidget(self.urlbar)
# 响应回车按钮,将浏览器当前访问的URL设置为用户输入的URL
def navigate_to_url(self):
current_url = QUrl(self.urlbar.text())
if current_url.scheme() == '':
current_url.setScheme('http')
self.tabs.currentWidget().load(current_url)
# 将当前网页的链接更新到地址栏
def renew_urlbar(self, url, browser=None):
# 非当前窗口不更新URL
if browser != self.tabs.currentWidget():
return
self.urlbar.setText(url.toString())
self.urlbar.setCursorPosition(0)
# 添加新的标签页
def add_new_tab(self, qurl=QUrl(''), label='Blank'):
# 设置浏览器
self.browser = WebView(self)
self.browser.load(qurl)
# 为标签添加索引方便管理
i = self.tabs.addTab(self.browser, label)
self.tabs.setCurrentIndex(i)
self.browser.urlChanged.connect(lambda qurl, browser=self.browser: self.renew_urlbar(qurl, self.browser))
# 将标签标题改为网页相关的标题
self.browser.loadFinished.connect(
lambda _, i=i, browser=self.browser: self.tabs.setTabText(i, self.browser.page().title()))
# 双击标签栏打开新页面
def tab_open(self, i):
if i == -1:
self.add_new_tab()
def current_tab_changed(self, i):
qurl = self.tabs.currentWidget().url()
self.renew_urlbar(qurl, self.tabs.currentWidget())
def close_current_tab(self, i):
# 若当前标签页只有一个则不关闭
if self.tabs.count() < 2:
return
self.tabs.removeTab(i)
if __name__ == '__main__':
my_application = QApplication(sys.argv) # 创建QApplication类的实例
main_demo = MainDemo()
main_demo.show()
my_application.exec_()
python的代码易于了解代码中还有解释,如果有看不懂的地方可以评论作者为你解析,好的本期的浏览器制作到此结束,谢谢大家的观看。
代码运行成功截图