pyqt6 简易浏览器

376 阅读2分钟

import os
import sys
from PyQt6.QtCore import Qt, QUrl, pyqtSignal, QTimer, QEvent
from PyQt6.QtWebEngineCore import QWebEngineSettings
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QPushButton, QWidget, QTabBar, \
    QFileDialog, QMessageBox, QHBoxLayout
from PyQt6.QtGui import QIcon
from PyQt6.QtWebEngineWidgets import QWebEngineView
from datetime import datetime


class QWebEngineView_New(QWebEngineView):
    htmlFinished = pyqtSignal()
    downsignal = pyqtSignal(str)
    js_result = pyqtSignal(str)

    def __init__(self, tabWidget):
        try:
            super(QWebEngineView_New, self).__init__()
            self._glwidget = None
            self.fatherWindow = tabWidget
            self.setMouseTracking(True)
            self.installEventFilter(self)
            # self.fatherWindow.installEventFilter(self)
            # 支持视频播放
            self.settings().setAttribute(QWebEngineSettings.WebAttribute.PluginsEnabled, True)
            self.settings().setAttribute(QWebEngineSettings.WebAttribute.PdfViewerEnabled, True)
            self.settings().setAttribute(QWebEngineSettings.WebAttribute.PrintElementBackgrounds, True)
            self.settings().setAttribute(QWebEngineSettings.WebAttribute.JavascriptEnabled, True)
            # 页面关闭请求
            self.page().windowCloseRequested.connect(self.OnWindowCloseRequested)
            # 页面下载请求
            self.page().profile().downloadRequested.connect(self.OnDownloadRequested)
            # 持久目录
            # self.page().profile().setPersistentStoragePath(self.persistent_path)
            # # 缓存目录
            # self.page().profile().setCachePath(self.cache_path)
            # # 下载目录
            # self.page().profile().setDownloadPath(self.default_dowload_folder)
            # self.js_result = False
        except Exception as e:
            print(e)

    def closeEvent(self, event):
        """"关闭调试器触发"""
        try:
            self.fatherWindow.inspectorClose()
        except Exception as e:
            print(e)

    def OnWindowCloseRequested(self):
        """"支持页面关闭请求"""
        try:
            the_index = self.fatherWindow.tabWidget.currentIndex()
            self.fatherWindow.tabWidget.removeTab(the_index)
        except Exception as e:
            print(e)

    def OnDownloadRequested(self, downloadItem):
        """"支持页面下载按钮"""
        downloadItem.downloadProgress.connect(
            lambda bytesReceived, bytesTotal: self._downloadProgress(bytesReceived, bytesTotal,
                                                                     downloadItem.url().fileName()))
        try:
            if downloadItem.isFinished() == False and downloadItem.state() == 0:
                the_filename = downloadItem.url().fileName()
                if len(the_filename) == 0 or "." not in the_filename:
                    cur_time = datetime.now().strftime('%Y%m%d%H%M%S')
                    the_filename = "下载文件" + cur_time + ".xls"

                temp = os.path.join('./', the_filename)
                filetype = "所有文件(*.*)" + ";;" + "*." + the_filename.split('.')[-1]
                filepath, _ = QFileDialog.getSaveFileName(self, "Save File", temp, filetype)

                downloadItem_url = downloadItem.url().toString()
                print('downloadItem_url:', downloadItem.url().toString())
                print('the_filename:', the_filename)

                downloadItem.setPath(filepath)
                downloadItem.accept()
                downloadItem.finished.connect(self.onDownloadfinished)
        except Exception as e:
            print(e)

    def _downloadProgress(self, bytesReceived, bytesTotal, fileName):
        # bytesReceived 当前下载值 ; bytesTotal 文件总大小值
        self.bytesReceived = bytesReceived
        self.bytesTotal = bytesTotal

    def onDownloadfinished(self):
        """下载结束触发函数"""
        try:
            print('下载结束触发函数')
            print('self.bytesTotal:', self.bytesTotal)
            # self.fatherWindow.closeTab(self.fatherWindow.tabWidget.count() - 1)
            if self.bytesTotal:
                self.show_message_box('下载成功')
        except Exception as e:
            print(e)

    def createWindow(self, QWebEnginePage_WebWindowType):  # QWebPage_WebWindowType
        """"重写createwindow()"""
        print('重写createwindow')
        try:
            new_webview = QWebEngineView_New(self.fatherWindow)
            new_webview.loadFinished.connect(lambda: self.load_finished(new_webview))
            self.fatherWindow.createTab(new_webview)
            return new_webview
        except Exception as e:
            print(e)

    def show_message_box(self, dialog_type):
        msg_box = QMessageBox()
        if dialog_type == "提示":
            msg_box.setWindowTitle("提示")
            msg_box.setText("收藏成功!")
        elif dialog_type == "警告":
            msg_box.setWindowTitle("警告")
            msg_box.setText("此网站已被收藏,请勿重复收藏!")
        elif dialog_type == '错误':
            msg_box.setWindowTitle("错误")
            msg_box.setText("收藏失败!")
        else:
            msg_box.setWindowTitle("提示")
            msg_box.setText(dialog_type)
        timer = QTimer(msg_box)
        timer.setInterval(2000)  # 设置超时时间2秒
        timer.start()
        msg_box.exec()

    def load_finished(self, new_webview):
        new_webview.page().toHtml(self.callable)

    def callable(self, data):
        pass

    def eventFilter(self, source, event):
        #  QWebEngineView 覆盖了 event() 方法(根据文档),所以它可能根本不调用 QWidget 事件处理程序
        if event.type() == QEvent.Type.MouseButtonPress:
            print(
                f'eventtype:{event.type()} ChildAdded: {QEvent.Type.ChildAdded} MouseButtonPress:{QEvent.Type.MouseButtonPress}')
            print(source is self._glwidget)
        if event.type() == QEvent.Type.ChildAdded and event.child().isWidgetType():
            self._glwidget = event.child()
            self._glwidget.installEventFilter(self)
        elif (event.type() == QEvent.Type.MouseButtonPress):
            print(Qt.MouseButton.LeftButton)
            print(QEvent.Type.MouseButtonPress)
        return super(QWebEngineView_New, self).eventFilter(source, event)


class MainWindow_Temp(QWidget):
    def __init__(self, parent=None):
        try:
            # super(MainWindow, self).__init__(*args, **kwargs)
            super(MainWindow_Temp, self).__init__()
            self.parent = parent
            self.layout = QVBoxLayout(self)
            # self.layout.setContentsMargins(0, 0, 0, 0)
            # self.browserUi = BrowserUi(self.parent)
            # self.layout.addWidget(self.browserUi)

            self.browser = QWebEngineView_New(self.parent)  # self 是将主窗口作为参数,传给浏览器
            # # self.browser.setMouseTracking(True)
            # # self.browser.installEventFilter(self)
            # # self.browser.setFocusPolicy(Qt.FocusPolicy.NoFocus)
            self.layout.addWidget(self.browser)
            self.setLayout(self.layout)
            self.setGeometry(300, 300, 300, 200)
            self.setWindowTitle('title')
        except Exception as e:
            print(e)




class MainWindow(QMainWindow):
    tableObject = []
    tableObjectUrl = []

    def __init__(self):
        super().__init__()
        self.setWindowTitle("lw")
        self.setGeometry(100, 100, 800, 600)

        self.tabWidget = QTabWidget(self)
        self.setCentralWidget(self.tabWidget)

        self.browser = MainWindow_Temp(self)
        # self.browser.setMouseTracking(True)
        # self.browser.installEventFilter(self)
        # self.browser.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        self.createTab(self.browser)

        layout = QVBoxLayout()
        button1 = QPushButton("切换到页面2")
        button1.clicked.connect(lambda: self.switch_page(2))
        layout.addWidget(button1)

        button2 = QPushButton("切换到页面1")
        button2.clicked.connect(lambda: self.switch_page(1))
        layout.addWidget(button2)

    def switch_page(self, index):
        self.tabWidget.setCurrentIndex(index - 1)

    def createTab(self, webview):
        self.tab = QWidget()
        self.tabWidget.addTab(self.tab, "新标签页")
        self.tabWidget.setCurrentWidget(self.tab)
        #####
        self.Layout = QHBoxLayout(self.tab)
        self.Layout.setContentsMargins(0, 0, 0, 0)
        self.Layout.addWidget(webview)

        self.tableObject.append(webview)
        index = self.tabWidget.currentIndex()
        self.consoleButQWidget(index)
        if index == 0:
            print('访问系统首页')
            self.tabWidget.setTabText(index, "系统首页")
            home_url = 'https://www.bing.com'
            self.browser.browser.setUrl(QUrl(home_url))
        webview.setStyleSheet("QTabWidget{outline:none;} QTabWidget::item{background-color:rgb(240,240,240)}")


    def consoleButQWidget(self, index):
        """关闭按钮重置"""
        try:
            if index == 0:
                # 设置第一个窗口不能关闭
                self.tabWidget.tabBar().setTabButton(index, QTabBar.ButtonPosition.RightSide, None)
        except Exception as e:
            print(e)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec())