如何在PyQt5中将TabBar置于ToolBar上方?
PyQt5实现标签栏在工具栏上方的浏览器布局
要实现Chrome、Edge等主流浏览器的标签栏在工具栏上方的布局,只需调整主窗口的布局结构,将QTabWidget的标签栏从原组件中分离,重新排列各部件的顺序即可。
修改步骤
- 创建主容器部件与垂直布局,作为窗口的中心部件
- 从QTabWidget中提取标签栏,将其放置在布局的最顶部
- 将导航工具栏添加到标签栏下方
- 将移除了标签栏的QTabWidget添加到工具栏下方
- 调整全屏切换逻辑,针对分离后的标签栏做显示/隐藏处理
修改后的完整代码
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets from operator import iconcat from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWebEngineWidgets import * from PyQt5.QtNetwork import * from PyQt5.QtPrintSupport import * import sys import os class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) # 创建主容器与布局 main_widget = QWidget() self.setCentralWidget(main_widget) main_layout = QVBoxLayout(main_widget) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(0) # 初始化标签页组件 self.tabs = QTabWidget() self.tabs.setDocumentMode(True) self.tabs.tabBarClicked.connect(self.tab_open_doubleclick) self.tabs.currentChanged.connect(self.current_tab_changed) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_current_tab) # 分离标签栏并添加到布局顶部 self.tab_bar = self.tabs.tabBar() self.tabs.setTabBar(None) main_layout.addWidget(self.tab_bar) # 导航工具栏 self.navtb = QToolBar("Navigation", movable=False) self.navtb.setStyleSheet("background-color: white;" "height : 50px;" ) self.navtb.setFixedHeight(50) main_layout.addWidget(self.navtb) # 将标签页组件添加到布局(已无顶部标签栏) main_layout.addWidget(self.tabs) # 状态栏 self.status = QStatusBar() self.setStatusBar(self.status) # 全局样式表 self.setStyleSheet(''' QTabBar::tab { color: #000; padding: 5px; border-top-left-radius: 10px; border-top-right-radius: 10px; width: 150px; } QTabBar::tab:selected { background: white; } ''') # 返回按钮 BackBtn = QPushButton() BackBtn.setText("←") self.navtb.addWidget(BackBtn) BackBtn.clicked.connect(lambda:self.tabs.currentWidget().back()) BackBtn.setFont(QFont('Arial', 13)) BackBtn.setStyleSheet("QPushButton" "{" "background-color : #FFFFFF;" "border-top-left-radius : 20px;" "border-top-right-radius : 20px; " "border-bottom-left-radius : 20px; " "border-bottom-right-radius : 20px;" "width: 40px;" "height: 40px;" "}" "QPushButton::hover" "{" "background-color : #EEEEEE;" "}" "QPushButton::pressed" "{" "background-color : #DDDDDD;" "}" ) BackBtn.show() self.placeholderspace = QLabel() self.navtb.addWidget(self.placeholderspace) # 前进按钮 ForBtn = QPushButton() ForBtn.setText("→") self.navtb.addWidget(ForBtn) ForBtn.clicked.connect(lambda:self.tabs.currentWidget().forward()) ForBtn.setFont(QFont('Arial', 13)) ForBtn.setStyleSheet("QPushButton" "{" "background-color : #FFFFFF;" "border-top-left-radius : 20px;" "border-top-right-radius : 20px; " "border-bottom-left-radius : 20px; " "border-bottom-right-radius : 20px;" "width: 40px;" "height: 40px;" "}" "QPushButton::hover" "{" "background-color : #EEEEEE;" "}" "QPushButton::pressed" "{" "background-color : #DDDDDD;" "}" ) ForBtn.show() self.placeholderspace2 = QLabel() self.navtb.addWidget(self.placeholderspace2) # 刷新按钮 RelBtn = QPushButton() RelBtn.setText("⟳") self.navtb.addWidget(RelBtn) RelBtn.clicked.connect(lambda:self.tabs.currentWidget().reload()) RelBtn.setFont(QFont('Arial', 13)) RelBtn.setStyleSheet("QPushButton" "{" "background-color : #FFFFFF;" "border-top-left-radius : 20px;" "border-top-right-radius : 20px; " "border-bottom-left-radius : 20px; " "border-bottom-right-radius : 20px;" "width: 40px;" "height: 40px;" "}" "QPushButton::hover" "{" "background-color : #EEEEEE;" "}" "QPushButton::pressed" "{" "background-color : #DDDDDD;" "}" ) RelBtn.show() self.placeholderspace3 = QLabel() self.navtb.addWidget(self.placeholderspace3) # 主页按钮 HomeBtn = QPushButton() HomeBtn.setText("⌂") self.navtb.addWidget(HomeBtn) HomeBtn.clicked.connect(self.navigate_home) HomeBtn.setFont(QFont('Arial', 13)) HomeBtn.setStyleSheet("QPushButton" "{" "background-color : #FFFFFF;" "border-top-left-radius : 20px;" "border-top-right-radius : 20px; " "border-bottom-left-radius : 20px; " "border-bottom-right-radius : 20px;" "width: 40px;" "height: 40px;" "}" "QPushButton::hover" "{" "background-color : #EEEEEE;" "}" "QPushButton::pressed" "{" "background-color : #DDDDDD;" "}" ) HomeBtn.show() self.placeholderspace4 = QLabel() self.navtb.addWidget(self.placeholderspace4) # 地址栏 QFontDatabase.addApplicationFont("Montserrat.tff") font = QFont("Arial", 12) self.urlBar = QLineEdit() self.urlBar.setStyleSheet( "border-top-left-radius : 15px;" "border-top-right-radius : 15px; " "border-bottom-left-radius : 15px; " "border-bottom-right-radius : 15px;" "background-color : #EEEEEE;" "padding-left : 20px;" "padding-right : 20px;" "height : 30px;" ) self.urlBar.setFont(font) self.urlBar.returnPressed.connect(self.navigate_to_url) self.urlBar.setPlaceholderText('Type URL of the Website') self.navtb.addWidget(self.urlBar) self.placeholderspace5 = QLabel() self.navtb.addWidget(self.placeholderspace5) # 停止按钮 StopBtn = QPushButton() StopBtn.setText("x") self.navtb.addWidget(StopBtn) StopBtn.clicked.connect(lambda:self.tabs.currentWidget().stop()) StopBtn.setFont(QFont('Arial', 10)) StopBtn.setStyleSheet("QPushButton" "{" "background-color : #FFFFFF;" "border-top-left-radius : 20px;" "border-top-right-radius : 20px; " "border-bottom-left-radius : 20px; " "border-bottom-right-radius : 20px;" "width: 40px;" "height: 40px;" "}" "QPushButton::hover" "{" "background-color : #EEEEEE;" "}" "QPushButton::pressed" "{" "background-color : #DDDDDD;" "}" ) StopBtn.show() self.placeholderspace6 = QLabel() self.navtb.addWidget(self.placeholderspace6) # 关于按钮 KCBtn = QPushButton() KCBtn.setText("About Us") self.navtb.addWidget(KCBtn) KCBtn.clicked.connect(self.navigate_koala) KCBtn.setFont(QFont('Arial', 10)) KCBtn.setStyleSheet("QPushButton" "{" "background-color : #FFFFFF;" "border-top-left-radius : 20px;" "border-top-right-radius : 20px; " "border-bottom-left-radius : 20px; " "border-bottom-right-radius : 20px;" "width: 100px;" "height: 40px;" "}" "QPushButton::hover" "{" "background-color : #EEEEEE;" "}" "QPushButton::pressed" "{" "background-color : #DDDDDD;" "}" ) KCBtn.show() # 添加初始标签页 self.add_new_tab(QUrl('file:///C:/Users/mayan/Desktop/Koala%20Software/Koala_SpaceShip_(Python_ED)/google.html'), 'homepage') self.setWindowTitle('Khanda SpaceShip New Tab') self.setWindowIcon(QIcon('icon.ico')) self.showMaximized() def add_new_tab(self, qurl=None, label = "Khanda SpaceShip"): if qurl is None: qurl = QUrl('file:///C:/Users/mayan/Desktop/Koala%20Software/Koala_SpaceShip_(Python_ED)/google.html') browser = QWebEngineView() browser.settings().setAttribute( QWebEngineSettings.FullScreenSupportEnabled, True ) browser.setUrl(qurl) i= self.tabs.addTab(browser, label) self.tabs.setCurrentIndex(i) browser.urlChanged.connect(lambda qurl, browser = browser : self.update_urlbar(qurl, browser)) browser.loadFinished.connect(lambda _, i= i, browser = browser : self.tabs.setTabText(i, browser.page().title())) browser.page().fullScreenRequested.connect( lambda request, browser=browser: self.handle_fullscreen_requested( request, browser ) ) self.tabs.setTabIcon(i, browser.icon()) browser.iconChanged.connect(lambda icon, browser=browser: self.update_icon(browser, icon)) def handle_fullscreen_requested(self, request, browser): request.accept() if request.toggleOn(): self.showFullScreen() self.statusBar().hide() self.navtb.hide() self.tab_bar.hide() else: self.showNormal() self.statusBar().show() self.navtb.show() self.tab_bar.show() def tab_open_doubleclick(self, i): if i == -1: self.add_new_tab() def current_tab_changed(self, i): qurl = self.tabs.currentWidget().url() self.update_urlbar(qurl, self.tabs.currentWidget()) self.update_title(self.tabs.currentWidget()) def close_current_tab(self, i): if self.tabs.count() < 1: return page = self.tabs.widget(i) self.tabs.removeTab(i) page.deleteLater() def update_icon(self, browser, icon): index = self.tabs.indexOf(browser) self.tabs.setTabIcon(index, icon) self.tab_bar.setTabIcon(index, icon) def update_title(self, browser): if browser != self.tabs.currentWidget(): return title = self.tabs.currentWidget().page().title() self.setWindowTitle("% s - Khanda SpaceShip" % title) def navigate_home(self): self.tabs.currentWidget().setUrl(QUrl("file:///C:/Users/mayan/Desktop/Koala%20Software/Koala_SpaceShip_(Python_ED)/google.html")) def navigate_koala(self): self.tabs.currentWidget().setUrl(QUrl("https://mayankadi99.github.io/khanda.github.io/index.html")) def navigate_to_url(self): q = QUrl(self.urlBar.text()) if q.scheme() == "": q.setScheme("https") self.tabs.currentWidget().setUrl(q) def update_urlbar(self, q, browser = None): if browser != self.tabs.currentWidget(): return self.urlBar.setText(q.toString()) self.urlBar.setCursorPosition(0) app = QApplication(sys.argv) app.setApplicationName("Khanda SpaceShip") app.setOrganizationName("Khanda Corparation") app.setOrganizationDomain("mkhanda.com") mw = MainWindow() mw.show() sys.exit(app.exec_())
关键修改说明
- 新增主容器与垂直布局,统一管理标签栏、工具栏和网页内容的顺序
- 将QTabWidget的标签栏分离为独立部件,放置在布局最顶部
- 调整全屏切换逻辑,针对分离后的
self.tab_bar进行显示/隐藏 - 更新
update_icon方法,同步更新分离标签栏的图标
内容的提问来源于stack exchange,提问作者Mayank Adi
相关产品推荐
相关产品推荐

