用PyQt5 写简易浏览器

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

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

先上图:

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

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

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

class TitleBar(QWidget):
    # 窗口最小化信号
    windowMinimumed = pyqtSignal()
    # 窗口最大化信号
    windowMaximumed = pyqtSignal()
    # 窗口还原信号
    windowNormaled = pyqtSignal()
    # 窗口关闭信号
    windowClosed = pyqtSignal()
    # 添加标签页信号
    addPaged = pyqtSignal()
    # 窗口移动
    windowMoved = pyqtSignal(QPoint)

    def __init__(self, *args, **kwargs):
        super(TitleBar, self).__init__(*args, **kwargs)
        # 支持qss设置背景
        self.setAttribute(Qt.WA_StyledBackground, True)
        self.mPos = None
        self.iconSize = 20  # 图标的默认大小
        # 设置默认背景颜色,否则由于受到父窗口的影响导致透明
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(palette.Window, QColor(240, 240, 240))
        self.setPalette(palette)
        # 布局
        self.layout = QHBoxLayout(self, spacing=0)
        # 功能按钮组
        # self.layout.addStretch()
        self.layout.setContentsMargins(0, 0, 0, 0)
        # 窗口图标
        # self.iconLabel = QLabel(self)
        # self.setIcon(QIcon(':/icons/logo.png'))
        # self.iconLabel.setScaledContents(True)
        # self.layout.addWidget(self.iconLabel)
        # 窗口标题
        # self.titleLabel = QLabel(self)
        # self.titleLabel.setMargin(0)
        # self.titleLabel.setText("安全浏览器")
        # self.layout.addWidget(self.titleLabel)

        # 中间伸缩条
        self.layout.addSpacerItem(QSpacerItem(
            40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))

    def loadFnBtn(self):
        # 利用Webdings字体来显示图标
        font = self.font() or QFont()
        font.setFamily('Webdings')

        # 添加新的标签页
        self.buttonAddPage = QPushButton(unichr(0xf067), self, clicked=self.addPaged.emit, font=fontawesome("far"),
                                         objectName='buttonAddPage')
        # self.buttonAddPage.setIconSize(QSize(16,16))
        # self.buttonAddPage.setIcon(QIcon(':/icons/plus.png'))

        self.layout.addWidget(self.buttonAddPage)
        # 最小化按钮
        self.buttonMinimum = QPushButton(
            '0', self, clicked=self.windowMinimumed.emit, font=font, objectName='buttonMinimum')
        self.layout.addWidget(self.buttonMinimum)
        # 最大化/还原按钮
        self.buttonMaximum = QPushButton(
            '1', self, clicked=self.showMaximized, font=font, objectName='buttonMaximum')
        self.layout.addWidget(self.buttonMaximum)
        # 关闭按钮
        self.buttonClose = QPushButton(
            'r', self, clicked=self.windowClosed.emit, font=font, objectName='buttonClose')
        self.layout.addWidget(self.buttonClose)
        # 初始高度
        self.setHeight()

    def showMaximized(self):
        if self.buttonMaximum.text() == '1':
            # 最大化
            self.buttonMaximum.setText('2')
            self.windowMaximumed.emit()
        else:  # 还原
            self.buttonMaximum.setText('1')
            self.windowNormaled.emit()

    def setHeight(self, height=34):
        """设置标题栏高度"""
        self.setMinimumHeight(height)
        self.setMaximumHeight(height)
        # 设置右边按钮的大小
        self.buttonMinimum.setMinimumSize(height, height)
        self.buttonMinimum.setMaximumSize(height, height)
        self.buttonMaximum.setMinimumSize(height, height)
        self.buttonMaximum.setMaximumSize(height, height)
        self.buttonClose.setMinimumSize(height, height)
        self.buttonClose.setMaximumSize(height, height)
        self.buttonAddPage.setMaximumSize(height, height)
        self.buttonAddPage.setMaximumSize(height, height)

    def setTitle(self, title):
        """设置标题"""
        self.titleLabel.setText(title)

    def setIcon(self, icon):
        """设置图标"""
        self.iconLabel.setPixmap(icon.pixmap(self.iconSize, self.iconSize))

    def setIconSize(self, size):
        """设置图标大小"""
        self.iconSize = size

    def enterEvent(self, event):
        self.setCursor(Qt.ArrowCursor)
        super(TitleBar, self).enterEvent(event)

    def mousePressEvent(self, event):
        """鼠标点击事件"""
        if event.button() == Qt.LeftButton:
            self.mPos = event.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        '''鼠标弹起事件'''
        self.mPos = None
        event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton and self.mPos:
            self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
        event.accept()

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

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

class TabBarDe(QTabBar):
    # 窗口移动
    windowMoved = pyqtSignal(QPoint)

    def __init__(self, _self):
        super().__init__()
        self._self = _self
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.rightMenuShow)

    def mousePressEvent(self, event):
        super(TabBarDe, self).mousePressEvent(event)
        """鼠标点击事件"""
        if event.button() == Qt.LeftButton:
            self.mPos = event.pos()
        self.cur_width = event.pos().x()
        event.accept()

    def mouseReleaseEvent(self, event):
        '''鼠标弹起事件'''
        super(TabBarDe, self).mouseReleaseEvent(event)
        self.mPos = None
        event.accept()

    def mouseMoveEvent(self, event):
        # print(event.pos().x(),event.pos().y())
        # print(self.size().width())
        # print(self._self.tab_)
        cur_width = len(self._self.tab_.values()) * 220
        if self.cur_width <= cur_width:
            super(TabBarDe, self).mouseMoveEvent(event)
        else:
            self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
        event.accept()

    def mouseDoubleClickEvent(self, event):
        super(TabBarDe, self).mouseDoubleClickEvent(event)
        self._self.titleBar.showMaximized()

    def rightMenuShow(self):
        try:
            self.contextMenu = QMenu()
            self.contextMenu.setFont(fontawesome("far"))
            index_action = QWidgetAction()
            index_button = QPushButton(unichr(0xf015),
                                       # clicked=self.zoom_out_func,
                                       font=fontawesome("far"), )
            index_button.setToolTip("主页")
            index_button.setCursor(Qt.ArrowCursor)
            index_action.setDefaultWidget(index_button)

            self.actionA = self.contextMenu.addAction(index_action)
            self.contextMenu.popup(QCursor.pos())  # 2菜单显示的位置
            # self.actionA.triggered.connect(self.actionHandler)
            self.contextMenu.show()
        except Exception as e:
            print(e)

    def actionHandler(self):
        print('action')

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

#创建QTabWidget
self.tabWidget = QTabWidget()
#创建一个新的QTabBar
self.tabBar = TabBarDe(self)
#替换QTabWidget默认的QTabBar
self.tabWidget.setTabBar(self.tabBar)

最后将QTabBar放入标题栏:

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

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

通过pyinstaller模块进行打包:

效果视频:

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

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

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值