如何在 PyQT5 中创建导航栏
How to create navigation bar in in PyQT5
我正准备在 qt 设计器中创建一个导航栏,但我不完全确定如何完成它。我的第一个想法是创建 3x Windows,顶部有三个按钮,分别称为“常规”、“交付”和“付款”。然后每当我点击其中一个按钮时,我将被引导至另一个 window。这是在 qt 设计器中创建导航栏的“正确”方法吗?
另一个想法是我要创建 1x window,但三个不同的框架,这样它只会在单击按钮时改变一个框架,而不是整个 window 本身。不幸的是,我完全不知道该怎么做。
布局示例:
一种可能的解决方案是使用修改后的 QTabWidget 并创建自定义页面:
from functools import cached_property
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Page(QtWidgets.QWidget):
completeChanged = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.container)
lay.addWidget(self.button, alignment=QtCore.Qt.AlignCenter)
self.button.clicked.connect(self.handle_clicked)
@cached_property
def container(self):
return QtWidgets.QWidget()
@cached_property
def button(self):
return QtWidgets.QPushButton("Save")
def handle_clicked(self):
if self.validate():
self.completeChanged.emit()
def validate(self):
# Override this method if you want to validate the entries,
# if it returns True then it will go to the next page,
# otherwise it will not move from the page
return True
class TabWizard(QtWidgets.QTabWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.tabBar().installEventFilter(self)
def eventFilter(self, obj, event):
if obj is self.tabBar() and event.type() == QtCore.QEvent.MouseButtonPress:
return True
return super().eventFilter(obj, event)
def addPage(self, page, title):
if not isinstance(page, Page):
raise TypeError(f"{page} must be Page object")
self.addTab(page, title)
page.completeChanged.connect(self.nextPage)
def nextPage(self):
next_index = self.currentIndex() + 1
if next_index < self.count():
self.setCurrentIndex(next_index)
class Page1(Page):
def __init__(self, parent=None):
super().__init__(parent)
lay = QtWidgets.QFormLayout(self.container)
lay.addRow("Foo1", QtWidgets.QLineEdit())
lay.addRow("Bar1", QtWidgets.QLineEdit())
class Page2(Page):
def __init__(self, parent=None):
super().__init__(parent)
lay = QtWidgets.QFormLayout(self.container)
lay.addRow("Foo2", QtWidgets.QLineEdit())
lay.addRow("Bar2", QtWidgets.QLineEdit())
class Widget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
tabwizard = TabWizard()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(tabwizard)
tabwizard.addPage(Page1(), "page1")
tabwizard.addPage(Page2(), "page2")
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
我正准备在 qt 设计器中创建一个导航栏,但我不完全确定如何完成它。我的第一个想法是创建 3x Windows,顶部有三个按钮,分别称为“常规”、“交付”和“付款”。然后每当我点击其中一个按钮时,我将被引导至另一个 window。这是在 qt 设计器中创建导航栏的“正确”方法吗?
另一个想法是我要创建 1x window,但三个不同的框架,这样它只会在单击按钮时改变一个框架,而不是整个 window 本身。不幸的是,我完全不知道该怎么做。
布局示例:
一种可能的解决方案是使用修改后的 QTabWidget 并创建自定义页面:
from functools import cached_property
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Page(QtWidgets.QWidget):
completeChanged = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.container)
lay.addWidget(self.button, alignment=QtCore.Qt.AlignCenter)
self.button.clicked.connect(self.handle_clicked)
@cached_property
def container(self):
return QtWidgets.QWidget()
@cached_property
def button(self):
return QtWidgets.QPushButton("Save")
def handle_clicked(self):
if self.validate():
self.completeChanged.emit()
def validate(self):
# Override this method if you want to validate the entries,
# if it returns True then it will go to the next page,
# otherwise it will not move from the page
return True
class TabWizard(QtWidgets.QTabWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.tabBar().installEventFilter(self)
def eventFilter(self, obj, event):
if obj is self.tabBar() and event.type() == QtCore.QEvent.MouseButtonPress:
return True
return super().eventFilter(obj, event)
def addPage(self, page, title):
if not isinstance(page, Page):
raise TypeError(f"{page} must be Page object")
self.addTab(page, title)
page.completeChanged.connect(self.nextPage)
def nextPage(self):
next_index = self.currentIndex() + 1
if next_index < self.count():
self.setCurrentIndex(next_index)
class Page1(Page):
def __init__(self, parent=None):
super().__init__(parent)
lay = QtWidgets.QFormLayout(self.container)
lay.addRow("Foo1", QtWidgets.QLineEdit())
lay.addRow("Bar1", QtWidgets.QLineEdit())
class Page2(Page):
def __init__(self, parent=None):
super().__init__(parent)
lay = QtWidgets.QFormLayout(self.container)
lay.addRow("Foo2", QtWidgets.QLineEdit())
lay.addRow("Bar2", QtWidgets.QLineEdit())
class Widget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
tabwizard = TabWizard()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(tabwizard)
tabwizard.addPage(Page1(), "page1")
tabwizard.addPage(Page2(), "page2")
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())