示例#1
0
class Statusbar():
    def __init__(self, main):
        self.main: QMainWindow = main

        self.statusbar = QStatusBar(main)
        self.statusbar.setEnabled(True)
        self.statusbar.setCursor(QCursor(Qt.ArrowCursor))
        self.statusbar.setAutoFillBackground(True)
        main.setStatusBar(self.statusbar)
        main.statusBar().showMessage('')

        # optionale Integration von Widgets in der Statusbar
        # self.label = QLabel()
        # self.label.setText('')
        #
        # self.btn_exit = QPushButton()
        # self.btn_exit.setIcon(QIcon('assets/icon/exit.ico'))
        # self.btn_exit.clicked.connect(self.main.close)
        #
        # self.statusbar.addWidget(self.label, stretch=1.0)  # fake spacer
        # self.statusbar.addWidget(self.btn_exit)
        # self.label.show()
        # self.btn_exit.show()
        # self.statusbar.show()

    def status_message(self, value):
        self.main.statusBar().showMessage(value)
class FramelessWindow(QWidget):
    # 四周边距
    Margins = 2
    # 窗口移动
    windowMoved = pyqtSignal(QPoint)

    def __init__(self):
        super(FramelessWindow, self).__init__()
        self.tab_ = {}
        self.initTab()
        # 初始化一个 tab
        self.newTab()

        self._pressed = False
        self.Direction = None
        # 背景透明
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        # 无边框
        self.setWindowFlags(Qt.FramelessWindowHint)  # 隐藏边框
        # 鼠标跟踪
        self.setMouseTracking(True)
        # 布局
        layout = QVBoxLayout(self, spacing=0)
        # 预留边界用于实现无边框窗口调整大小
        layout.setContentsMargins(self.Margins, self.Margins, self.Margins, self.Margins)
        # 标题栏
        self.titleBar = TitleBar(self)
        # layout = QGridLayout(self, spacing=0)
        # layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.titleBar)
        # self.titleBar.layout.addChildWidget(self.tabWidget.tabBar())
        # self.layout().addWidget(self.titleBar)
        self.titleBar.layout.addChildWidget(self.tabWidget.tabBar())
        self.titleBar.loadFnBtn()
        # self.addPage = QAction(QIcon(':/icons/plus.png'), '页面缩小', self)
        # QTabBar.setS
        self.layout().addWidget(self.tabWidget)
        self.titleBar.addPaged.connect(self.newTab)

        self.statusBar = QStatusBar()
        layout.addWidget(self.statusBar)
        self.headStatusBarLabel = QLabel("就绪")
        self.headStatusBarLabel.setObjectName("headStatusBarLabel")
        self.statusBar.addWidget(self.headStatusBarLabel)

        # 网页加载标签
        self.statusBarLabel = QLabel("网页加载")
        self.statusBarLabel.setObjectName("statusBarLabel")
        self.statusBar.addPermanentWidget(self.statusBarLabel)

        # 网页加载进度条
        self.statusBarLabelProgress = QProgressBar(self)
        self.statusBar.addPermanentWidget(self.statusBarLabelProgress)
        self.statusBarLabelProgress.setObjectName("statusBarLabelProgress")
        self.statusBarLabelProgress.setFixedWidth(200)
        self.statusBarLabelProgress.setHidden(True)
        self.statusBarLabel.setHidden(True)
        # 文件下载标签
        self.statusBarDownloadLabel = QLabel("")
        self.statusBarDownloadLabel.setObjectName("statusBarDownloadLabel")
        self.statusBar.addPermanentWidget(self.statusBarDownloadLabel)
        self.statusBarDownloadLabel.setHidden(True)

        self.statusBar.setHidden(True)
        self.statusBar.setCursor(Qt.ArrowCursor)

        # 信号槽
        self.titleBar.windowMinimumed.connect(self.showMinimized)
        self.titleBar.windowMaximumed.connect(self.showMaximized)
        self.titleBar.windowNormaled.connect(self.showNormal)
        self.titleBar.windowClosed.connect(self.close)
        self.tabBar.windowMoved.connect(self.move)
        # self.titleBar.windowMoved.connect(self.move)
        # self.windowTitleChanged.connect(self.titleBar.setTitle)
        # self.windowIconChanged.connect(self.titleBar.setIcon)
        self.show()

    def initTab(self):
        # print("initTab")
        # self.setWindowFlags(Qt.FramelessWindowHint)  # 去掉标题栏的代码
        # 设置窗口标题
        self.setWindowTitle('PyQt浏览器 v2.0')
        # 设置窗口图标
        self.setWindowIcon(QIcon(':/icons/logo.png'))
        self.tabWidget = QTabWidget()
        # self.tabWidget.setTabBarAutoHide(True)
        self.tabBar = TabBarDe(self)
        # self.tabBar.addAction()
        self.tabWidget.setTabBar(self.tabBar)
        # self.tabWidget.setTabShape(QTabWidget.Triangular) # QTabWidget.Triangular
        self.tabWidget.setDocumentMode(True)
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.tabCloseRequested.connect(self.close_Tab)
        self.tabWidget.currentChanged.connect(self.changeTab)

        # self.tabWidget.tabBar().setAutoHide(True)
        height = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) // 2
        width = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) // 2
        self.setMinimumSize(QSize(height * 0.7, width * 0.7))
        # self.center()
        # self.show()

    def newTab(self):
        # print("new tab")
        test = QPushButton("test")
        self.tab = QWidget()
        self.tabWidget.addTab(self.tab, "新标签页")
        self.tabWidget.setCurrentWidget(self.tab)
        index = self.tabWidget.currentIndex()
        try:
            self.tabWidget.setTabIcon(index, QIcon(":icons/earth_128.png"))
        except BaseException as base:
            print(base)
        #####
        self.Layout = QVBoxLayout(self.tab)
        self.Layout.setContentsMargins(0, 0, 0, 0)
        self.browser = Browser(self)
        self.browser.webview.setObjectName(str(index))
        self.tab.setObjectName("tab_" + str(index))
        self.tab_[str(index)] = self.browser.webview
        self.Layout.addWidget(self.browser)

    # 关闭tab
    def close_Tab(self, index):
        if self.tabWidget.count() > 1:
            # self.browser.webview.page().url(QUrl(""))
            # print(self.tab_[str(index)])

            webObj_index = str(self.tabWidget.widget(index).objectName()).split("_")[1]
            # self.tab_[webObj_index].page().setUrl(QUrl(NEW_PAGE))
            # self.tab_[webObj_index].deleteLater()
            print(self.tab_[webObj_index].history())
            self.tab_.pop(webObj_index)
            # print(self.tab_)
            self.tabWidget.removeTab(index)
            # print(index)
            # self.browser.on_windowCloseRequested()
        else:
            self.close()  # 当只有1个tab时,关闭主窗口

    def changeTab(self, index):
        # print("index:%d" % (index))
        pass

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def setTitleBarHeight(self, height=34):
        """设置标题栏高度"""
        self.titleBar.setHeight(height)

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

    def setWidget(self, widget):
        """设置自己的控件"""
        if hasattr(self, '_widget'):
            return
        self._widget = widget
        # 设置默认背景颜色,否则由于受到父窗口的影响导致透明
        self._widget.setAutoFillBackground(True)
        palette = self._widget.palette()
        palette.setColor(palette.Window, QColor(240, 240, 240))
        self._widget.setPalette(palette)
        self._widget.installEventFilter(self)
        self.layout().addWidget(self._widget)

    def move(self, pos):
        if self.windowState() == Qt.WindowMaximized or self.windowState() == Qt.WindowFullScreen:
            # 最大化或者全屏则不允许移动
            return
        super(FramelessWindow, self).move(pos)

    def showMaximized(self):
        """最大化,要去除上下左右边界,如果不去除则边框地方会有空隙"""
        super(FramelessWindow, self).showMaximized()
        self.layout().setContentsMargins(0, 0, 0, 0)

    def showFullScreen(self):
        super(FramelessWindow, self).showFullScreen()
        self.layout().setContentsMargins(0, 0, 0, 0)

    def showNormal(self):
        """还原,要保留上下左右边界,否则没有边框无法调整"""
        super(FramelessWindow, self).showNormal()
        self.layout().setContentsMargins(
            self.Margins, self.Margins, self.Margins, self.Margins)

    def eventFilter(self, obj, event):
        """事件过滤器,用于解决鼠标进入其它控件后还原为标准鼠标样式"""
        if isinstance(event, QEnterEvent):
            self.setCursor(Qt.ArrowCursor)
        return super(FramelessWindow, self).eventFilter(obj, event)

    def paintEvent(self, event):
        """由于是全透明背景窗口,重绘事件中绘制透明度为1的难以发现的边框,用于调整窗口大小"""
        super(FramelessWindow, self).paintEvent(event)
        painter = QPainter(self)
        painter.setPen(QPen(QColor(255, 255, 255, 1), 2 * self.Margins))
        painter.drawRect(self.rect())

    def mousePressEvent(self, event):
        """鼠标点击事件"""
        super(FramelessWindow, self).mousePressEvent(event)
        if event.button() == Qt.LeftButton:
            self._mpos = event.pos()
            self._pressed = True

    def mouseReleaseEvent(self, event):
        '''鼠标弹起事件'''
        super(FramelessWindow, self).mouseReleaseEvent(event)
        self._pressed = False
        self.Direction = None

    def mouseMoveEvent(self, event):
        """鼠标移动事件"""
        super(FramelessWindow, self).mouseMoveEvent(event)
        pos = event.pos()
        xPos, yPos = pos.x(), pos.y()
        wm, hm = self.width() - self.Margins, self.height() - self.Margins
        if self.isMaximized() or self.isFullScreen():
            self.Direction = None
            self.setCursor(Qt.ArrowCursor)
            return
        if event.buttons() == Qt.LeftButton and self._pressed:
            self._resizeWidget(pos)
            return
        if xPos <= self.Margins and yPos <= self.Margins:
            # 左上角
            self.Direction = LeftTop
            self.setCursor(Qt.SizeFDiagCursor)
        elif wm <= xPos <= self.width() and hm <= yPos <= self.height():
            # 右下角
            self.Direction = RightBottom
            self.setCursor(Qt.SizeFDiagCursor)
        elif wm <= xPos and yPos <= self.Margins:
            # 右上角
            self.Direction = RightTop
            self.setCursor(Qt.SizeBDiagCursor)
        elif xPos <= self.Margins and hm <= yPos:
            # 左下角
            self.Direction = LeftBottom
            self.setCursor(Qt.SizeBDiagCursor)
        elif 0 <= xPos <= self.Margins and self.Margins <= yPos <= hm:
            # 左边
            self.Direction = Left
            self.setCursor(Qt.SizeHorCursor)
        elif wm <= xPos <= self.width() and self.Margins <= yPos <= hm:
            # 右边
            self.Direction = Right
            self.setCursor(Qt.SizeHorCursor)
        elif self.Margins <= xPos <= wm and 0 <= yPos <= self.Margins:
            # 上面
            self.Direction = Top
            self.setCursor(Qt.SizeVerCursor)
        elif self.Margins <= xPos <= wm and hm <= yPos <= self.height():
            # 下面
            self.Direction = Bottom
            self.setCursor(Qt.SizeVerCursor)

    def _resizeWidget(self, pos):
        """调整窗口大小"""
        if self.Direction == None:
            return
        mpos = pos - self._mpos
        xPos, yPos = mpos.x(), mpos.y()
        geometry = self.geometry()
        x, y, w, h = geometry.x(), geometry.y(), geometry.width(), geometry.height()
        if self.Direction == LeftTop:  # 左上角
            if w - xPos > self.minimumWidth():
                x += xPos
                w -= xPos
            if h - yPos > self.minimumHeight():
                y += yPos
                h -= yPos
        elif self.Direction == RightBottom:  # 右下角
            if w + xPos > self.minimumWidth():
                w += xPos
                self._mpos = pos
            if h + yPos > self.minimumHeight():
                h += yPos
                self._mpos = pos
        elif self.Direction == RightTop:  # 右上角
            if h - yPos > self.minimumHeight():
                y += yPos
                h -= yPos
            if w + xPos > self.minimumWidth():
                w += xPos
                self._mpos.setX(pos.x())
        elif self.Direction == LeftBottom:  # 左下角
            if w - xPos > self.minimumWidth():
                x += xPos
                w -= xPos
            if h + yPos > self.minimumHeight():
                h += yPos
                self._mpos.setY(pos.y())
        elif self.Direction == Left:  # 左边
            if w - xPos > self.minimumWidth():
                x += xPos
                w -= xPos
            else:
                return
        elif self.Direction == Right:  # 右边
            if w + xPos > self.minimumWidth():
                w += xPos
                self._mpos = pos
            else:
                return
        elif self.Direction == Top:  # 上面
            if h - yPos > self.minimumHeight():
                y += yPos
                h -= yPos
            else:
                return
        elif self.Direction == Bottom:  # 下面
            if h + yPos > self.minimumHeight():
                h += yPos
                self._mpos = pos
            else:
                return
        self.setGeometry(x, y, w, h)