程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-05(4)

用PyQt5 写简易浏览器

发布于2020-02-28 12:30     阅读(1484)     评论(0)     点赞(26)     收藏(3)


一时兴起,一边学习PyQt5,一边写简易浏览器半成品。。。

最近发现Electron,手里的PyQt突然就不香了。。。

先上图:

关于PyQt5的依赖安装就不多bibi了。。。

首先要重写窗口标题栏和功能按钮。。。

手写标题栏,通过重写QWidget实现横向布局,放入窗口控制按钮(最小化,最大化,还原,关闭):

  1. class TitleBar(QWidget):
  2. # 窗口最小化信号
  3. windowMinimumed = pyqtSignal()
  4. # 窗口最大化信号
  5. windowMaximumed = pyqtSignal()
  6. # 窗口还原信号
  7. windowNormaled = pyqtSignal()
  8. # 窗口关闭信号
  9. windowClosed = pyqtSignal()
  10. # 添加标签页信号
  11. addPaged = pyqtSignal()
  12. # 窗口移动
  13. windowMoved = pyqtSignal(QPoint)
  14. def __init__(self, *args, **kwargs):
  15. super(TitleBar, self).__init__(*args, **kwargs)
  16. # 支持qss设置背景
  17. self.setAttribute(Qt.WA_StyledBackground, True)
  18. self.mPos = None
  19. self.iconSize = 20 # 图标的默认大小
  20. # 设置默认背景颜色,否则由于受到父窗口的影响导致透明
  21. self.setAutoFillBackground(True)
  22. palette = self.palette()
  23. palette.setColor(palette.Window, QColor(240, 240, 240))
  24. self.setPalette(palette)
  25. # 布局
  26. self.layout = QHBoxLayout(self, spacing=0)
  27. # 功能按钮组
  28. # self.layout.addStretch()
  29. self.layout.setContentsMargins(0, 0, 0, 0)
  30. # 窗口图标
  31. # self.iconLabel = QLabel(self)
  32. # self.setIcon(QIcon(':/icons/logo.png'))
  33. # self.iconLabel.setScaledContents(True)
  34. # self.layout.addWidget(self.iconLabel)
  35. # 窗口标题
  36. # self.titleLabel = QLabel(self)
  37. # self.titleLabel.setMargin(0)
  38. # self.titleLabel.setText("安全浏览器")
  39. # self.layout.addWidget(self.titleLabel)
  40. # 中间伸缩条
  41. self.layout.addSpacerItem(QSpacerItem(
  42. 40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
  43. def loadFnBtn(self):
  44. # 利用Webdings字体来显示图标
  45. font = self.font() or QFont()
  46. font.setFamily('Webdings')
  47. # 添加新的标签页
  48. self.buttonAddPage = QPushButton(unichr(0xf067), self, clicked=self.addPaged.emit, font=fontawesome("far"),
  49. objectName='buttonAddPage')
  50. # self.buttonAddPage.setIconSize(QSize(16,16))
  51. # self.buttonAddPage.setIcon(QIcon(':/icons/plus.png'))
  52. self.layout.addWidget(self.buttonAddPage)
  53. # 最小化按钮
  54. self.buttonMinimum = QPushButton(
  55. '0', self, clicked=self.windowMinimumed.emit, font=font, objectName='buttonMinimum')
  56. self.layout.addWidget(self.buttonMinimum)
  57. # 最大化/还原按钮
  58. self.buttonMaximum = QPushButton(
  59. '1', self, clicked=self.showMaximized, font=font, objectName='buttonMaximum')
  60. self.layout.addWidget(self.buttonMaximum)
  61. # 关闭按钮
  62. self.buttonClose = QPushButton(
  63. 'r', self, clicked=self.windowClosed.emit, font=font, objectName='buttonClose')
  64. self.layout.addWidget(self.buttonClose)
  65. # 初始高度
  66. self.setHeight()
  67. def showMaximized(self):
  68. if self.buttonMaximum.text() == '1':
  69. # 最大化
  70. self.buttonMaximum.setText('2')
  71. self.windowMaximumed.emit()
  72. else: # 还原
  73. self.buttonMaximum.setText('1')
  74. self.windowNormaled.emit()
  75. def setHeight(self, height=34):
  76. """设置标题栏高度"""
  77. self.setMinimumHeight(height)
  78. self.setMaximumHeight(height)
  79. # 设置右边按钮的大小
  80. self.buttonMinimum.setMinimumSize(height, height)
  81. self.buttonMinimum.setMaximumSize(height, height)
  82. self.buttonMaximum.setMinimumSize(height, height)
  83. self.buttonMaximum.setMaximumSize(height, height)
  84. self.buttonClose.setMinimumSize(height, height)
  85. self.buttonClose.setMaximumSize(height, height)
  86. self.buttonAddPage.setMaximumSize(height, height)
  87. self.buttonAddPage.setMaximumSize(height, height)
  88. def setTitle(self, title):
  89. """设置标题"""
  90. self.titleLabel.setText(title)
  91. def setIcon(self, icon):
  92. """设置图标"""
  93. self.iconLabel.setPixmap(icon.pixmap(self.iconSize, self.iconSize))
  94. def setIconSize(self, size):
  95. """设置图标大小"""
  96. self.iconSize = size
  97. def enterEvent(self, event):
  98. self.setCursor(Qt.ArrowCursor)
  99. super(TitleBar, self).enterEvent(event)
  100. def mousePressEvent(self, event):
  101. """鼠标点击事件"""
  102. if event.button() == Qt.LeftButton:
  103. self.mPos = event.pos()
  104. event.accept()
  105. def mouseReleaseEvent(self, event):
  106. '''鼠标弹起事件'''
  107. self.mPos = None
  108. event.accept()
  109. def mouseMoveEvent(self, event):
  110. if event.buttons() == Qt.LeftButton and self.mPos:
  111. self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
  112. event.accept()

添加QTabWidget()到主窗口,将QTabWidget内置的QTabBar()重写并放入TitleBar()中。。。

以下代码是重写QTabBar(),在Chrome中标题栏和选项卡是融合的,所以我们要让QTabBar()实现标题栏的拖动功能:

  1. class TabBarDe(QTabBar):
  2. # 窗口移动
  3. windowMoved = pyqtSignal(QPoint)
  4. def __init__(self, _self):
  5. super().__init__()
  6. self._self = _self
  7. self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
  8. self.customContextMenuRequested.connect(self.rightMenuShow)
  9. def mousePressEvent(self, event):
  10. super(TabBarDe, self).mousePressEvent(event)
  11. """鼠标点击事件"""
  12. if event.button() == Qt.LeftButton:
  13. self.mPos = event.pos()
  14. self.cur_width = event.pos().x()
  15. event.accept()
  16. def mouseReleaseEvent(self, event):
  17. '''鼠标弹起事件'''
  18. super(TabBarDe, self).mouseReleaseEvent(event)
  19. self.mPos = None
  20. event.accept()
  21. def mouseMoveEvent(self, event):
  22. # print(event.pos().x(),event.pos().y())
  23. # print(self.size().width())
  24. # print(self._self.tab_)
  25. cur_width = len(self._self.tab_.values()) * 220
  26. if self.cur_width <= cur_width:
  27. super(TabBarDe, self).mouseMoveEvent(event)
  28. else:
  29. self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
  30. event.accept()
  31. def mouseDoubleClickEvent(self, event):
  32. super(TabBarDe, self).mouseDoubleClickEvent(event)
  33. self._self.titleBar.showMaximized()
  34. def rightMenuShow(self):
  35. try:
  36. self.contextMenu = QMenu()
  37. self.contextMenu.setFont(fontawesome("far"))
  38. index_action = QWidgetAction()
  39. index_button = QPushButton(unichr(0xf015),
  40. # clicked=self.zoom_out_func,
  41. font=fontawesome("far"), )
  42. index_button.setToolTip("主页")
  43. index_button.setCursor(Qt.ArrowCursor)
  44. index_action.setDefaultWidget(index_button)
  45. self.actionA = self.contextMenu.addAction(index_action)
  46. self.contextMenu.popup(QCursor.pos()) # 2菜单显示的位置
  47. # self.actionA.triggered.connect(self.actionHandler)
  48. self.contextMenu.show()
  49. except Exception as e:
  50. print(e)
  51. def actionHandler(self):
  52. print('action')

接下来是创建QTabWidget()的代码片段:

  1. #创建QTabWidget
  2. self.tabWidget = QTabWidget()
  3. #创建一个新的QTabBar
  4. self.tabBar = TabBarDe(self)
  5. #替换QTabWidget默认的QTabBar
  6. self.tabWidget.setTabBar(self.tabBar)

最后将QTabBar放入标题栏:

  1. # addChildWidget()这是我们重写的标题栏方法
  2. self.titleBar.layout.addChildWidget(self.tabWidget.tabBar())

这个小项目整体实现了基本的网页浏览、文件下载、标签栏、页面缩放等,可能还有写BUG没有解决。。。

通过pyinstaller模块进行打包:

效果视频:

PyQt5 完成浏览器开发编译运行

github:https://github.com/tt20050510/PyQt5-HowardChrome



所属网站分类: 技术文章 > 博客

作者:紫薇

链接:https://www.pythonheidong.com/blog/article/235898/e13af98d3063c68e7433/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

26 0
收藏该文
已收藏

评论内容:(最多支持255个字符)