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

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

1、创建一个MainWindow

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

然后在左侧containers中添加Stacked Widget这个控件,初步布局如下:
在这里插入图片描述

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

2、创建页面

2.1 修改当前页名称

在右侧属性中修改当前页名称,把第一页修改为page_first
在这里插入图片描述

2.2 增加页

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

第一页增加输入框:账号、密码:
在这里插入图片描述

第二页增加显示框:
在这里插入图片描述

第三页增加显示框:
在这里插入图片描述

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, QtWidgetsclass 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.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.btn_first.setText(_translate("MainWindow", "首页"))self.textBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:16pt; color:#0000ff;\">PyQt5通过堆叠布局实现选项卡(多界面)功能</span></p></body></html>"))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 timefrom PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal, QMutexfrom PyQt5 import QtCorefrom stacked import Ui_MainWindowclass 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):# 功能1self.stackedWidget.setCurrentIndex(1)def btn_fun2_clicked(self):# 功能2self.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 - time1days = diff.daysseconds = diff.secondsself.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 += stlself.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 = parentself.is_exit = Falsedef run(self):while 1:self.qmut.lock()if self.is_exit:breakself.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、效果

在这里插入图片描述

登录界面:
在这里插入图片描述

注册界面:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/131449.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【100天精通Python】Day61:Python 数据分析_Pandas可视化功能:绘制饼图,箱线图,散点图,散点图矩阵,热力图,面积图等(示例+代码)

目录 1 Pandas 可视化功能 2 Pandas绘图实例 2.1 绘制线图 2.2 绘制柱状图 2.3 绘制随机散点图 2.4 绘制饼图 2.5 绘制箱线图A 2.6 绘制箱线图B 2.7 绘制散点图矩阵 2.8 绘制面积图 2.9 绘制热力图 2.10 绘制核密度估计图 1 Pandas 可视化功能 pandas是一个强大的数…

常驻巨噬细胞诱导的纤维化在胰腺炎性损伤和PDAC中具有不同的作用

介绍一篇2023年8月10日发表在Nature Immunology的文章 标题&#xff1a; Fibrosis induced by resident macrophages has divergent roles in pancreas inflammatory injury and PDAC 影响因子&#xff1a;30.5 DOI&#xff1a;https://doi.org/10.1038/s41590-023-01579-x …

web端动效 PAG

之前写过一篇lottie动效的文章&#xff1a;web端动效 lottie-web 使用&#xff0c;本篇写一下PAG-web的基础使用。 PAG是腾讯开发&#xff0c;支持移动端、桌面端以及Web端的动效工作流解决方案。目标是降低或消除动效相关的研发成本&#xff0c;能够一键将设计师在 AE&#x…

TensorFlow 03(Keras)

一、tf.keras tf.keras是TensorFlow 2.0的高阶API接口&#xff0c;为TensorFlow的代码提供了新的风格和设计模式&#xff0c;大大提升了TF代码的简洁性和复用性&#xff0c;官方也推荐使用tf.keras来进行模型设计和开发。 1.1 tf.keras中常用模块 如下表所示: 1.2 常用方法 …

Ei Scopus检索 | 2024年第四届能源与环境工程国际会议(CoEEE 2024)

会议简介 Brief Introduction 2024年第四届能源与环境工程国际会议(CoEEE 2024) 会议时间&#xff1a;2023年5月22日-24日 召开地点&#xff1a;意大利米兰 大会官网&#xff1a;www.coeee.org CoEEE 2024将围绕“能源与环境工程”的最新研究领域而展开&#xff0c;为研究人员、…

VSCODE 使用技巧

vscode批量去掉代码中空行的方法 1、在vscode中使用ctrl f组合快捷键打开替换窗口. 2、输入下面的正则表达式 ^\s*(?\r?$)\n https://mp.weixin.qq.com/s/ZKV2sZWszxBLNTNLEWhsng

springboot redisTemplate.opsForValue().setIfAbsent返回null原理

一、版本 springboot版本&#xff1a;spring-boot-starter-data-redis 2.1.6 redisson版本&#xff1a;redisson-spring-boot-starter 3.11.5 二、场景 Boolean res redisTemplate.opsForValue().setIfAbsent("key","value");以上代码同一时间多次执行…

Sentinel控制台配置 持久化到nacos

sentinel控制台&#xff0c;使用方便&#xff0c;功能强大。使用官方的jar包&#xff0c;配置不会持久化&#xff0c;sentinel重启后会导致&#xff0c;之前的规则全部丢失&#xff0c;下面一起改造源码实现规则数据的持久化 sentinel源码地址 &#xff08;github访问太慢&am…

嵌入式学习笔记(25)串口通信的基本原理

三根通信线&#xff1a;Tx Rx GND &#xff08;1&#xff09;任何通信都要有信息作为传输载体&#xff0c;或者有线的或则无线的。 &#xff08;2&#xff09;串口通信时有线通信&#xff0c;是通过串口线来通信的。 &#xff08;3&#xff09;串口通信最少需要2根&#xff…

MCU芯片测试:性能指标测试痛点是什么?ATECLOUD能否解决?

MCU芯片测试指标的核心是性能指标&#xff0c;包括处理器性能、存储器容量和读写速度&#xff0c;外设性能等。芯片测试对自动化测试的要求很高&#xff0c;ATECLOUD-IC不仅解决了传统测试方法的问题&#xff0c;而且也可以满足芯片测试的高要求&#xff0c;高效地完成MCU芯片性…

ChartJS使用-环境搭建(vue)

1、介绍 Chartjs简约不简单的JavaScript的图表库。官网https://chart.nodejs.cn/ Chart.js 带有内置的 TypeScript 类型&#xff0c;并与所有流行的 JavaScript 框架 兼容&#xff0c;包括 React 、Vue 、Svelte 和 Angular 。 你可以直接使用 Chart.js 或利用维护良好的封装程…

SpringBoot课堂笔记20230913

本篇文章为SpringBoot学习笔记&#xff0c;方便自己再复习。 Maven&#xff1a;jar包管理工具 注解&#xff1a; Controller:处理http请求&#xff0c;返回的视图 RestController: 相当于ResponseBody和Controller一起用&#xff0c;返回的是json ResponseBody:返回响应内容 …

自动化监控系统PrometheusGrafana

Prometheus 算是一个全能型选手&#xff0c;原生支持容器监控&#xff0c;当然监控传统应用也不是吃干饭的&#xff0c;所以就是容器和非容器他都支持&#xff0c;所有的监控系统都具备这个流程&#xff0c;数据采集→数据处理→数据存储→数据展示→告警 Prometheus 特点展开…

摩洛哥6.9级地震 网络出现轻度中断

北京时间2023年9月9日6时11分(当地时间8日23时11分)&#xff0c;摩洛哥发生6.9级强震。埃文科技的监测数据显示&#xff0c;受地震影响&#xff0c;摩洛哥地区的网络也出现了轻度中断。 9月9日6时10分后&#xff0c;摩洛哥地区活跃前缀数量开始减少&#xff0c;在6时50分左右达…

利用 Python 中的地理空间数据与 GeoPandas

推荐&#xff1a;使用 NSDT编辑器快速搭建3D应用场景 空间数据的真正潜力在于它能够连接数据点及其各自的位置&#xff0c;为高级分析创造无限的可能性。地理空间数据科学是数据科学中的一个新兴领域&#xff0c;旨在利用地理空间信息并通过空间算法和机器学习或深度学习等先进…

算法通关村第十九关:白银挑战-动态规划高频问题

白银挑战-动态规划高频问题 1. 最少硬币数 LeetCode 322 https://leetcode.cn/problems/coin-change/description/ 思路分析 尝试用回溯来实现 假如coins[2,5,7]&#xff0c;amount27&#xff0c;求解过程中&#xff0c;每个位置都可以从[2,5,7]中选择&#xff0c;因此可以…

error:Failed building wheel for XXX

解决方案适用于大多数的pip 安装时出现的Failed building wheel for XXX 出现问题 按以往快速安装包的经验&#xff0c;第一反应当然是使用简单又快捷的terminal命令加上镜像&#xff0c;如下&#xff1a; pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple结…

关闭训练过程中的wandb

训练的过程中反复提醒wandb的账户&#xff0c;自动化执行的话&#xff0c;不是很方便&#xff0c;因此需要关闭这个wandb的功能 提醒的方式是这样的&#xff1a; 解决办法1、注释掉wandb相关的代码&#xff0c;并且添加关闭命令&#xff1a;wandb None 参考&#xff1a; 训…

儿童折叠式和非折叠式椅子和凳子加拿大认证标准要求介绍 ASTM F2613-21

儿童折叠式和非折叠式椅子和凳子是带有刚性框架的座椅家具&#xff0c;用于支撑儿童的身体&#xff0c;使其可以直立或倾斜的姿势坐立或休息。 此次合规要求更新适用于儿童折叠式和非折叠式椅子和凳子。这类产品可以折叠起来&#xff0c;以便运输或储存。儿童椅是带有刚性框架的…

05JVM_类加载阶段

一、类加载阶段 1.加载 1.1介绍 ①Java源代码经编译生成字节码文件&#xff0c;通过类加载阶段将字节码载入方法区。 ②类加载阶段内部是C的instanceKlass描述java类&#xff0c;重要的域field有: _java_mirror&#xff0c;java类镜像。例如对String来说&#xff0c;就是St…