PyQt5 切换页面 StackedWidget
效果
说明
设置了两个 Frame
,一个为左边内部组件为垂直布局的按钮集合,一个为右边用于 页面切换
的方形区域,宽度比为 1 : 5
。
初始化 stackedWidget
# 以父 Frame 为父组件,构建完整覆盖父 Frame 的空间
self.stackedWidget = QtWidgets.QStackedWidget(self.frame_2)
self.stackedWidget.setGeometry(QtCore.QRect(0, 0, 651, 551))
self.stackedWidget.setObjectName("stackedWidget")
成员加入 stackedWidget
# 声明一个页面
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
# 通过方法配置 Tab ,类似于 Page
self.setTabs_Page_1_Frame_2()
# 将该页面加入 stackedWidget
self.stackedWidget.addWidget(self.page)
# 声明第 2 个页面
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
......
# 将该页面加入 stackedWidget
self.stackedWidget.addWidget(self.page_2)
# 声明第 3 个页面
self.page_3 = QtWidgets.QWidget()
self.page_3.setObjectName("page_3")
......
# 将该页面加入 stackedWidget
self.stackedWidget.addWidget(self.page_3)
切换调用 stackedWidget
要将 Frame 2
页面内容切换,需要指定 stackedWidget
的索引,第一个添加的页面对应索引为 0
。
self.stackedWidget.setCurrentIndex(0)
按钮调用 stackedWidget
在 Frame 1
中声明了三个 PushButton
,通过 clicked
点击触发切换函数。
因为自定义槽函数需要使用到 lambda
匿名函数,请参考 PyQt5 信号、槽函数和 lambda 匿名函数 。
self.pushButton.clicked.connect(lambda: self.printStr("123"))
源码
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def __init__(self):
self.centralwidget = None
self.menubar = None
self.layoutWidget = None
self.horizontalLayout = None
self.widget = None
self.verticalLayout = None
self.fileMenu = None
self.fileMenuAction = None
self.fileMenuAction_2 = None
self.fileMenuAction_3 = None
self.pushButton = None
self.pushButton_2 = None
self.pushButton_3 = None
self.frame = None
self.frame_2 = None
self.stackedWidget = None
self.tabWidget = None
self.tab = None
self.tab_2 = None
self.page = None
self.page_2 = None
self.page_3 = None
self.label = None
self.label_2 = None
self.label_3 = None
self.label_4 = None
self.action = None
self.action_2 = None
self.action_3 = None
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget.setGeometry(QtCore.QRect(0, 0, 791, 551))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.setMenu(MainWindow)
self.setFrame_1()
self.setFrame_2()
MainWindow.setCentralWidget(self.centralwidget)
self.setActions(MainWindow)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(0)
self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "页面1"))
self.pushButton_2.setText(_translate("MainWindow", "页面2"))
self.pushButton_3.setText(_translate("MainWindow", "页面3"))
# Page 1
self.label.setText(_translate("MainWindow", "TextLabel 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
self.label_2.setText(_translate("MainWindow", "TextLabel 2"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
# Page 2
self.label_3.setText(_translate("MainWindow", "Page 2"))
# Page 3
self.label_4.setText(_translate("MainWindow", "Page 3"))
# Actions
self.action.setText(_translate("MainWindow", "action"))
self.action_2.setText(_translate("MainWindow", "action_2"))
self.action_3.setText(_translate("MainWindow", "action_3"))
def setActions(self, MainWindow):
self.action = QtWidgets.QAction(MainWindow)
self.action.setObjectName("action")
self.action_2 = QtWidgets.QAction(MainWindow)
self.action_2.setObjectName("action_2")
self.action_3 = QtWidgets.QAction(MainWindow)
self.action_3.setObjectName("action_3")
def setFrame_1(self):
"""
主界面左侧 3 个按钮定为 1 个 Frame ,内部组件采用垂直布局
:return:
"""
self.frame = QtWidgets.QFrame(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
self.frame.setSizePolicy(sizePolicy)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.widget = QtWidgets.QWidget(self.frame)
self.widget.setGeometry(QtCore.QRect(0, 0, 131, 551))
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.setPushButton_Frame_1()
self.horizontalLayout.addWidget(self.frame)
def setPushButton_Frame_1(self):
"""
对 Frame 1 的按钮进行声明 和 点击触发方法 配置
:return:
"""
self.pushButton = QtWidgets.QPushButton(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setObjectName("pushButton")
# 加入垂直布局列表
self.verticalLayout.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth())
self.pushButton_2.setSizePolicy(sizePolicy)
self.pushButton_2.setObjectName("pushButton_2")
self.verticalLayout.addWidget(self.pushButton_2)
self.pushButton_3 = QtWidgets.QPushButton(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth())
self.pushButton_3.setSizePolicy(sizePolicy)
self.pushButton_3.setObjectName("pushButton_3")
self.verticalLayout.addWidget(self.pushButton_3)
# 点击触发方法
# self.pushButton.clicked.connect(self.gotoStack_1)
self.pushButton.clicked.connect(lambda: self.gotoStack(0))
self.pushButton_2.clicked.connect(lambda: self.gotoStack(1))
self.pushButton_3.clicked.connect(lambda: self.gotoStack(2))
def setFrame_2(self):
self.frame_2 = QtWidgets.QFrame(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(5)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
self.frame_2.setSizePolicy(sizePolicy)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.stackedWidget = QtWidgets.QStackedWidget(self.frame_2)
self.stackedWidget.setGeometry(QtCore.QRect(0, 0, 651, 551))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.stackedWidget.sizePolicy().hasHeightForWidth())
self.stackedWidget.setSizePolicy(sizePolicy)
self.stackedWidget.setObjectName("stackedWidget")
self.setPages_Frame_2()
self.horizontalLayout.addWidget(self.frame_2)
def setPages_Frame_2(self):
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.setTabs_Page_1_Frame_2()
self.stackedWidget.addWidget(self.page)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.label_3 = QtWidgets.QLabel(self.page_2)
self.label_3.setGeometry(QtCore.QRect(180, 230, 281, 111))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
self.label_3.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(28)
self.label_3.setFont(font)
self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.stackedWidget.addWidget(self.page_2)
self.page_3 = QtWidgets.QWidget()
self.page_3.setObjectName("page_3")
self.label_4 = QtWidgets.QLabel(self.page_3)
self.label_4.setGeometry(QtCore.QRect(190, 240, 281, 111))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
self.label_4.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(28)
self.label_4.setFont(font)
self.label_4.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
self.stackedWidget.addWidget(self.page_3)
def setTabs_Page_1_Frame_2(self):
self.tabWidget = QtWidgets.QTabWidget(self.page)
self.tabWidget.setGeometry(QtCore.QRect(-10, 0, 661, 551))
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.label = QtWidgets.QLabel(self.tab)
self.label.setGeometry(QtCore.QRect(180, 200, 281, 111))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(28)
self.label.setFont(font)
self.label.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.label_2 = QtWidgets.QLabel(self.tab_2)
self.label_2.setGeometry(QtCore.QRect(190, 210, 281, 111))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
self.label_2.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(28)
self.label_2.setFont(font)
self.label_2.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.tabWidget.addTab(self.tab_2, "")
def gotoStack(self, index: int):
"""
Frame 2 的第 index 个界面, index = 0
:param index:
:return:
"""
self.stackedWidget.setCurrentIndex(index)
def setMenu(self, MainWindow):
"""
配置菜单栏
:return:
"""
# 声明菜单栏
"""
self.menubar = QtWidgets.QMenuBar(self.ui)
等同于
self.menubar = QtWidgets.QMenuBar()
self.ui.setMenuBar(self.menubar)
"""
self.menubar = QtWidgets.QMenuBar()
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menubar.setObjectName("menubar")
# 添加菜单组件
self.fileMenu = QtWidgets.QMenu(self.menubar)
self.fileMenu.setObjectName("fileMenu")
self.fileMenu.setTitle("文件")
# 添加单一组件
self.fileMenuAction = QtWidgets.QAction("Page 1")
self.fileMenuAction.triggered.connect(self.gotoStack_1)
self.fileMenuAction_2 = QtWidgets.QAction("Page 2")
self.fileMenuAction_2.triggered.connect(self.gotoStack_2)
self.fileMenuAction_3 = QtWidgets.QAction("Page 3")
self.fileMenuAction_3.triggered.connect(self.gotoStack_3)
# 构建文件菜单
self.fileMenu.addAction(self.fileMenuAction)
self.fileMenu.addSeparator()
self.fileMenu.addAction(self.fileMenuAction_2)
self.fileMenu.addSeparator()
self.fileMenu.addAction(self.fileMenuAction_3)
# 构建菜单栏
self.menubar.addAction(self.fileMenu.menuAction())
MainWindow.setMenuBar(self.menubar)
if __name__ == "__main__":
# 创建活跃 app 句柄
app = QtWidgets.QApplication(sys.argv)
# 关闭全部窗口后程序不退出
app.setQuitOnLastWindowClosed(False)
# 声明界面句柄
mainWindow = QtWidgets.QMainWindow()
# 构建程序界面
ui = Ui_MainWindow()
ui.setupUi(mainWindow)
# 程序启动时打开主界面
mainWindow.show()
sys.exit(app.exec_())