class StatusbarUI(object): def __init__(self, main_window: QMainWindow): """ 状态栏 外观模式 :param main_window: """ self.main_window = main_window self.statusbar = QStatusBar(self.main_window) self.ui_list = [] self.show_time = ShowTime(self.statusbar, 1) # 时间模块 self.placeholder = Placeholder(self.statusbar, 2) # 占位符 self.net_speed = NetSpeed(self.statusbar, -4) # 网速 self.monitor_port = MonitorPort(self.statusbar, -3) # 监听端口 self.online_host = OnlineHost(self.statusbar, -1) # 上线主机 def options(self) -> None: font = QFont() font.setPointSize(10) self.statusbar.setFont(font) # self.statusbar.setGeometry(QtCore.QRect(0, 0, 900, 50)) self.statusbar.setFixedHeight(30) self.main_window.setStatusBar(self.statusbar) # self.main_window.setStatusBar() # self.statusbar.setContextMenuPolicy(Qt.DefaultContextMenu) def setup_ui(self) -> None: self.statusbar.setObjectName("statusbar") self.options() self.load_ui() self.show_ui() if not settings.STATUSBAR_SHOW: self.statusbar.setHidden(False) # noinspection PyArgumentList def retranslate_ui(self) -> None: self.statusbar.setWindowTitle(_translate("StatusbarUI", "状态栏")) def load_ui(self) -> None: """ 加载模块 :return: """ self.ui_list.append(self.show_time) self.ui_list.append(self.placeholder) self.ui_list.append(self.net_speed) self.ui_list.append(self.monitor_port) self.ui_list.append(self.online_host) def show_ui(self) -> None: """ 显示数据 :return: """ for view in self.ui_list: view.setup_ui() view.retranslate_ui()
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)