PyQt5通过堆叠布局实现选项卡(多界面)功能

PyQt5通过堆叠布局实现选项卡(多界面)功能

Demo例程下载

点我下载

https://download.csdn.net/download/lm_is_dc/88335301

1、创建一个MainWindow

加入Text Brower做标题,几个按钮。

然后在左侧containers中添加Stacked Widget这个控件,初步布局如下:
PyQt5通过堆叠布局实现选项卡(多界面)功能_第1张图片

  • 对窗口中的堆叠容器 “Stacked Widget”,选中后可以用鼠标拖动、拉伸来调整控件的位置和大小,或者在 “属性编辑器” 中设置 (X, Y)、宽度、高度属性。
  • 堆叠容器 “Stacked Widget” 自动建立了 2个页面。鼠标位于堆叠容器 “Stacked Widget” ,右键唤出下拉菜单,选择 "插入页"可以插入新的页面,选择 “改变页顺序” 可以调整各页面的顺序。
  • 在控件的右上角显示有一对黑色三角符号,可以在多个页面之间切换,也可以在 “对象查看器” 中选择要编辑的页面。

2、创建页面

2.1 修改当前页名称

在右侧属性中修改当前页名称,把第一页修改为page_first
PyQt5通过堆叠布局实现选项卡(多界面)功能_第2张图片

2.2 增加页

选中Stacked Widget,右键插入页->当前页之后,增加两页,并命名为page_fun1,page_fun2

第一页增加输入框:账号、密码:
PyQt5通过堆叠布局实现选项卡(多界面)功能_第3张图片

第二页增加显示框:
PyQt5通过堆叠布局实现选项卡(多界面)功能_第4张图片

第三页增加显示框:
PyQt5通过堆叠布局实现选项卡(多界面)功能_第5张图片

3、把ui转成py

转化后代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'stacked.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.btn_first = QtWidgets.QPushButton(self.centralwidget)
        self.btn_first.setGeometry(QtCore.QRect(50, 100, 93, 28))
        self.btn_first.setObjectName("btn_first")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(45, 10, 711, 41))
        self.textBrowser.setObjectName("textBrowser")
        self.btn_fun1 = QtWidgets.QPushButton(self.centralwidget)
        self.btn_fun1.setGeometry(QtCore.QRect(170, 100, 93, 28))
        self.btn_fun1.setObjectName("btn_fun1")
        self.btn_fun2 = QtWidgets.QPushButton(self.centralwidget)
        self.btn_fun2.setGeometry(QtCore.QRect(280, 100, 93, 28))
        self.btn_fun2.setObjectName("btn_fun2")
        self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget)
        self.stackedWidget.setGeometry(QtCore.QRect(50, 160, 691, 271))
        self.stackedWidget.setObjectName("stackedWidget")
        self.page_first = QtWidgets.QWidget()
        self.page_first.setObjectName("page_first")
        self.label = QtWidgets.QLabel(self.page_first)
        self.label.setGeometry(QtCore.QRect(70, 50, 72, 21))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.page_first)
        self.label_2.setGeometry(QtCore.QRect(70, 90, 72, 21))
        self.label_2.setObjectName("label_2")
        self.account_edit = QtWidgets.QLineEdit(self.page_first)
        self.account_edit.setGeometry(QtCore.QRect(130, 50, 113, 21))
        self.account_edit.setObjectName("account_edit")
        self.password_edit = QtWidgets.QLineEdit(self.page_first)
        self.password_edit.setGeometry(QtCore.QRect(130, 90, 113, 21))
        self.password_edit.setObjectName("password_edit")
        self.btn_login = QtWidgets.QPushButton(self.page_first)
        self.btn_login.setGeometry(QtCore.QRect(130, 140, 93, 28))
        self.btn_login.setObjectName("btn_login")
        self.btn_registere = QtWidgets.QPushButton(self.page_first)
        self.btn_registere.setGeometry(QtCore.QRect(250, 140, 93, 28))
        self.btn_registere.setObjectName("btn_registere")
        self.stackedWidget.addWidget(self.page_first)
        self.page_fun1 = QtWidgets.QWidget()
        self.page_fun1.setObjectName("page_fun1")
        self.label_3 = QtWidgets.QLabel(self.page_fun1)
        self.label_3.setGeometry(QtCore.QRect(60, 50, 72, 21))
        self.label_3.setObjectName("label_3")
        self.show_text_1 = QtWidgets.QTextBrowser(self.page_fun1)
        self.show_text_1.setGeometry(QtCore.QRect(170, 40, 256, 192))
        self.show_text_1.setObjectName("show_text_1")
        self.stackedWidget.addWidget(self.page_fun1)
        self.page_fun2 = QtWidgets.QWidget()
        self.page_fun2.setObjectName("page_fun2")
        self.label_4 = QtWidgets.QLabel(self.page_fun2)
        self.label_4.setGeometry(QtCore.QRect(60, 30, 72, 21))
        self.label_4.setObjectName("label_4")
        self.show_text_2 = QtWidgets.QTextBrowser(self.page_fun2)
        self.show_text_2.setGeometry(QtCore.QRect(130, 20, 256, 192))
        self.show_text_2.setObjectName("show_text_2")
        self.stackedWidget.addWidget(self.page_fun2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 27))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.stackedWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btn_first.setText(_translate("MainWindow", "首页"))
        self.textBrowser.setHtml(_translate("MainWindow", "\n"
"\n"
"

PyQt5通过堆叠布局实现选项卡(多界面)功能

"
)) self.btn_fun1.setText(_translate("MainWindow", "功能1")) self.btn_fun2.setText(_translate("MainWindow", "功能2")) self.label.setText(_translate("MainWindow", "账号")) self.label_2.setText(_translate("MainWindow", "密码")) self.btn_login.setText(_translate("MainWindow", "登录")) self.btn_registere.setText(_translate("MainWindow", "注册")) self.label_3.setText(_translate("MainWindow", "功能1")) self.label_4.setText(_translate("MainWindow", "功能2"))

4、QStackedWidget 类说明

QStackedWidget 类继承自 QFrame类。

QStackedWidge t类提供了多页面切换的布局,一次只能看到一个界面。

QStackedWidget 类的信号:

currentChanged(int index):当前页面发生变化时候发射,index 为新的索引值。
widgetRemoved(int index):页面被移除时候发射,index 为页面对应的索引值。

QStackedWidget 类的槽函数:

setCurrentIndex(int index):设置索引 index 所在的页面为当前页面。setCurrentWidget(QWidget *widget):设置QWidget页面为当前页面。

使用如下程序可以设置 page_0 为当前显示的页面:

pageNo = 0  # 设置 page_0 为索引页(第一页面)
self.stackedWidget.setCurrentIndex(pageNo)  # 设置使用 pageNo=0 作为当前显示页面

需要注意的是,不论我们为每个页面控件设置的名称(objectName)是什么,在 QStackedWidget 类中定义的页面索引 index 都是一个从 0 开始计数,即:第一页面的索引值 index=0,第二页面的索引值 index=1,…。

5、通过按钮来实现界面切换

示例代码:

# -*- coding: utf-8 -*-

"""
@contact: 微信 1257309054
@file: main.py
@time: 2023/9/13 15:09
@author: LDC
"""
import datetime
import json
import sys
import time

from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal, QMutex

from PyQt5 import QtCore

from stacked import Ui_MainWindow


class StackedDemo(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(StackedDemo, self).__init__()
        self.setupUi(self)  # 创建窗体对象
        self.init()

    def init(self):
        '''
        初始化
        :return:
        '''
        self.is_login = False  # 是否登录
        self.is_register = False  # 是否注册
        self.show_text_1_list = []  # 功能1显示内容列表
        self.show_text_2_list = []  # 功能1显示内容列表
        self.login_thread = LoginThread(self)  # 开启多线程处理登录数据
        # 关联按钮事件
        self.btn_first.clicked.connect(self.btn_first_clicked)  # 首页按钮点击事件
        self.btn_fun1.clicked.connect(self.btn_fun1_clicked)  # 功能1按钮点击事件
        self.btn_fun2.clicked.connect(self.btn_fun2_clicked)  # 功能2按钮点击事件
        self.btn_login.clicked.connect(self.btn_login_clicked)  # 登录按钮点击事件
        self.btn_registere.clicked.connect(self.btn_register_clicked)  # 注册按钮点击事件
        self.login_thread._signal_login.connect(self.threading_slot)  # 绑定线程回调处理函数

    def btn_first_clicked(self):
        # 首页
        self.stackedWidget.setCurrentIndex(0)

    def btn_fun1_clicked(self):
        # 功能1
        self.stackedWidget.setCurrentIndex(1)

    def btn_fun2_clicked(self):
        # 功能2
        self.stackedWidget.setCurrentIndex(2)

    def btn_login_clicked(self):
        # 登录
        self.stackedWidget.setCurrentIndex(1)  # 切换界面
        if not self.is_login:
            self.show_text_1_list.append('功能1界面--登录')
            self.login_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            self.show_text_1_list.append('登录时间:{}'.format(self.login_time))
        self.is_login = True  # 修改登录标志
        if self.is_login:
            self.login_thread.start()

    def btn_register_clicked(self):
        # 注册
        self.stackedWidget.setCurrentIndex(2)
        self.show_text_2.setText('功能2界面--注册')

    def threading_slot(self, data):
        '''
        线程回调函数
        :param data:
        :return:
        '''
        data = json.loads(data)
        if 'update_login_time' in data:
            if len(self.show_text_1_list) > 6:
                self.show_text_1_list.pop(0)
            now_time = data['update_login_time']
            time1 = datetime.datetime.strptime(self.login_time, '%Y-%m-%d %H:%M:%S')
            time2 = datetime.datetime.strptime(now_time, '%Y-%m-%d %H:%M:%S')

            diff = time2 - time1
            days = diff.days
            seconds = diff.seconds
            self.show_text_1_list.append(
                '\r\n{},已登录{}秒'.format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), seconds))
            info_msg = ''
            for stl in self.show_text_1_list:
                info_msg += stl
            self.show_text_1.setText(info_msg)


# 登录后处理
class LoginThread(QThread):
    # 登录多线程
    _signal_login = pyqtSignal(str)

    def __init__(self, parent=None):
        super(LoginThread, self).__init__(parent)
        self.qmut = QMutex()
        self.window = parent
        self.is_exit = False

    def run(self):
        while 1:
            self.qmut.lock()
            if self.is_exit:
                break
            self.qmut.unlock()
            now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            self._signal_login.emit(json.dumps({'update_login_time': now_time}))  # 发送信号给槽函数
            time.sleep(5)


if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)  # 自适应分辨率

    app = QtWidgets.QApplication(sys.argv)
    ui = StackedDemo()
    ui.show()
    sys.exit(app.exec_())


通过线程来演示切换界面时,之前的界面功能不受影响。

6、效果

PyQt5通过堆叠布局实现选项卡(多界面)功能_第6张图片

登录界面:
PyQt5通过堆叠布局实现选项卡(多界面)功能_第7张图片

注册界面:
PyQt5通过堆叠布局实现选项卡(多界面)功能_第8张图片

你可能感兴趣的:(pyqt5,qt,开发语言)