QStackedWidget
是 Qt 中用于管理多个界面切换的容器控件,它允许将多个子窗口(或页面)堆叠在一起,但每次只显示其中一个。常用于实现向导式界面、多步骤表单或动态切换的视图。以下是 QStackedWidget
的使用详解和示例:
基本用法
1. 创建并添加页面
from PyQt5.QtWidgets import QApplication, QWidget, QStackedWidget, QVBoxLayout, QLabel, QPushButton
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.stacked_widget = QStackedWidget()
self.init_ui()
def init_ui(self):
# 创建 3 个页面
page1 = QLabel("这是页面 1")
page2 = QLabel("这是页面 2")
page3 = QLabel("这是页面 3")
# 将页面添加到 QStackedWidget
self.stacked_widget.addWidget(page1)
self.stacked_widget.addWidget(page2)
self.stacked_widget.addWidget(page3)
# 创建切换按钮
btn_prev = QPushButton("上一页")
btn_next = QPushButton("下一页")
btn_prev.clicked.connect(self.show_previous_page)
btn_next.clicked.connect(self.show_next_page)
# 布局
layout = QVBoxLayout()
layout.addWidget(self.stacked_widget)
layout.addWidget(btn_prev)
layout.addWidget(btn_next)
self.setLayout(layout)
def show_previous_page(self):
# 获取当前索引,并切换到上一页
current = self.stacked_widget.currentIndex()
if current > 0:
self.stacked_widget.setCurrentIndex(current - 1)
def show_next_page(self):
# 获取当前索引,并切换到下一页
current = self.stacked_widget.currentIndex()
if current < self.stacked_widget.count() - 1:
self.stacked_widget.setCurrentIndex(current + 1)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
关键方法
-
添加/移除页面:
addWidget(widget)
:添加一个页面。insertWidget(index, widget)
:在指定位置插入页面。removeWidget(widget)
:移除页面。
-
切换页面:
setCurrentIndex(index)
:通过索引切换页面(从 0 开始)。setCurrentWidget(widget)
:直接切换到指定控件。
-
获取信息:
currentIndex()
:返回当前页面索引。currentWidget()
:返回当前显示的控件。count()
:返回页面总数。
结合导航控件
通常与 QComboBox
、QListWidget
或按钮结合使用,实现导航逻辑:
# 示例:通过 QComboBox 切换页面
combo = QComboBox()
combo.addItems(["Page 1", "Page 2", "Page 3"])
combo.currentIndexChanged.connect(self.stacked_widget.setCurrentIndex)
layout.addWidget(combo)
动态添加/删除页面
def add_dynamic_page(self):
new_page = QLabel(f"动态页面 {self.stacked_widget.count() + 1}")
self.stacked_widget.addWidget(new_page)
def remove_current_page(self):
current_widget = self.stacked_widget.currentWidget()
if current_widget:
self.stacked_widget.removeWidget(current_widget)
current_widget.deleteLater() # 释放内存
动画效果
Qt 默认不提供切换动画,但可以通过自定义实现淡入淡出或滑动效果。例如使用 QPropertyAnimation
:
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve
def switch_page_with_animation(self, index):
# 创建动画
animation = QPropertyAnimation(self.stacked_widget, b"pos")
animation.setDuration(300)
animation.setEasingCurve(QEasingCurve.OutQuad)
# 当前页面向左滑出,新页面向右滑入
current_pos = self.stacked_widget.pos()
animation.setStartValue(current_pos)
animation.setEndValue(current_pos - QPoint(100, 0))
animation.start()
# 切换页面后重置位置
self.stacked_widget.setCurrentIndex(index)
self.stacked_widget.move(current_pos + QPoint(100, 0))
典型场景
- 向导式界面:分步骤填写表单。
- 设置面板:通过侧边栏切换不同设置页。
- 动态视图切换:如列表视图/网格视图切换。
注意事项
- 确保页面切换逻辑不会导致索引越界(例如
currentIndex >= count()
)。 - 如果页面包含大量资源,移除时调用
deleteLater()
防止内存泄漏。 - 使用
QStackedWidget
时,通常需要自行管理导航逻辑(如按钮或菜单)。
通过灵活使用 QStackedWidget
,可以轻松实现复杂的多界面切换功能!