当前位置: 首页 > news >正文

PyQt5实战——操作台打印重定向,主界面以及stacklayout使用(四)

个人博客:苏三有春的博客
系类往期文章:
PyQt5实战——多脚本集合包,前言与环境配置(一)
PyQt5实战——多脚本集合包,UI以及工程布局(二)
PyQt5实战——多脚本集合包,程序入口QMainWindow(三)

PyQt主窗口框架设计(QWidget)

PrimeWindow.py的主要作用是绘制主窗口,在主窗口中:

  • 最左边是各种功能组件的入口,比如:翻译器,UTF-8转换,图像处理等。
  • 按下左边的按键,则会切换功能区,切换功能并非重新开一个窗口,而是切换中间部分,这里主要是采用stack的原理
  • 最右边是日志打印区,通过重定向的方法,把打印在操作台的内容打印到这个窗口上,这样方便开发人员debug

4.1 import部分

import Classes.TranslatorClass as TranslatorClass
import Classes.ConvertorClass as ConvertorClass
import Classes.AudioProcessClass as AudioProcessClass
import Classes.AudiocodecClass as AudiocodecClass
import Classes.AudioPlayerClass as AudioPlayerClass
import Classes.ImgProcessClass as ImgProcessClass
from component.btnStyle import *
from component.editStyle import *

这些引用均来自作者自己的代码,分别保存在Classes目录下和component目录下,从这些目录下import不同的类或方法供PrimeWindow调用。

Classes中的各种类,如TranslatorClass,保存着翻译功能的功能区UI结构:翻译按钮,翻译内容输入框以及翻译结果展示框等,以及各组件的摆放位置。

component中的各种方法,如btnStyle,该文件中有按钮按下的样式,按钮抬起的样式等,只需在点击按钮时调用该方法即可改变按钮样式。

4.2 重定向操作台输出

重定向操作台输出需要调用一些系统方法

        current_directory = os.getcwd() # 获取当前工作目录,并将其存储在current_directory中。self.original_stdout = sys.stdout # 将当前的标准输出(操作台)保存到self.original_stdout中,这样可以在将来恢复标准输出self.output_stream = io.StringIO() # 创建一个StringIO对象,这个对象像一个文件,可以在内存中操作字符串,之后的标准输入输出将写入这个对象sys.stdout = self.output_stream # 将标准输出重定向到刚才创建的StringIO对象self.output_stream。这样,所有通过print语句输出的信息都将储存在output_stream中,而不是打印到操作台self.timer = QTimer() # 创建一个定时器对象,用于定期触发某些事件self.timer.timeout.connect(self.updateOutput) # 将定时器的信号连接到self.updateOutput方法上,当定时器达到超时时间时则会调用该方法self.timer.start(1000) # 设置定时器的超时时间为1000ms即1s

以上实现的是:重定向操作台的输出,开启定时器,每1s后,将原本pirnt方法打印到操作台的字符串储存起来,并调用updateOutput方法

以下是代码逐行分析:

  • 获取当前工作目录,并将其存储在current_directory中
  • 将当前的标准输出(操作台)保存到self.original_stdout中,这样可以在将来恢复标准输出
  • 创建一个StringIO对象,这个对象像一个文件,可以在内存中操作字符串,之后的标准输入输出将写入这个对象
  • 将标准输出重定向到刚才创建的StringIO对象self.output_stream。这样,所有通过print语句输出的信息都将储存在output_stream中,而不是打印到操作台
  • 创建一个定时器对象,用于定期触发某些事件
  • 将定时器的信号连接到self.updateOutput方法上,当定时器达到超时时间时则会调用该方法
  • 设置定时器的超时时间为1000ms即1s

updateOutput方法:

    def updateOutput(self):output = self.output_stream.getvalue() # 从output_stream中获取字符串if output: # 如果其中有字符串的话cursor = self.consoleedit.textCursor() # 获取日志打印文本编辑控件的当前光标,方便在特定的位置插入文本cursor.movePosition(QTextCursor.End) # 将光标移动至结尾,以便现有文本插入新的输出内容cursor.insertText(output) # 将内容添加到日志打印文本编辑控件中self.consoleedit.setTextCursor(cursor) # 更新光标位置为刚刚移动的光标,这确保了后续的输入或操作将从正确的位置开始self.consoleedit.ensureCursorVisible() # 确保光标在文本编辑器中可见,特别是光标在底部时,防止用户无法看到最新的插入内容,尤其是文本框不够大时self.output_stream.truncate(0) # 清空output_stream中的内容,将其内容截断为0,使得下一轮输出时不会将之前的内容重复添加

通过这个方法,即可将打印的内容输出到日志打印区中。并每1秒就检查一次是否有新的内容需要输出

  • 因为是利用定时器每1秒检查一次是否有新的输出内容,所以输出并不是实时进行的,如你需要更精确的日志打印,则调小定时器的超时时间,但请注意,定时器的超时时间越短,定时器就会越频繁地调用updateOutput方法,即使什么新内容也没有。如果你需要做一些复杂且精密的操作,则可能需要考虑时间与空间开销的问题。

以下是代码逐行分析:

  • 从output_stream中获取字符串
  • 如果其中有字符串的话
  • 获取日志打印文本编辑控件的当前光标,方便在特定的位置插入文本
  • 将光标移动至结尾,以便现有文本插入新的输出内容
  • 将内容添加到日志打印文本编辑控件中
  • 更新光标位置为刚刚移动的光标,这确保了后续的输入或操作将从正确的位置开始
  • 确保光标在文本编辑器中可见,特别是光标在底部时,防止用户无法看到最新的插入内容,尤其是文本框不够大时
  • 清空output_stream中的内容,将其内容截断为0,使得下一轮输出时不会将之前的内容重复添加

4.3 stackLayout 切换功能

在PyQt中,QStackLayout是用于在同一位置上堆叠多个小组件的布局管理器,允许根据需要在它们之间进行切换,这对实现标签页或动态内容展示非常有用

    def create_stack(self):# create a stack layoutself.stacklayout = QStackedLayout()convertor = ConvertorClass.Wconvertor()self.stacklayout.addWidget(convertor)
  • 创建stacklayout
  • 把功能UI实现的对象添加在stacklayout中
        # set the convertor buttonsself.UTF8ConvertorBtn = QPushButton("UTF-8 转换") # 创建按钮对象btnReleaseStyleA(self.UTF8ConvertorBtn) # 修改按钮样式,该方法为作者创建,并非第三方库调用self.UTF8ConvertorBtn.clicked.connect(self.Cbtn_press_clicked) # 为按钮连接触发事件,该事件会切换stack# add the buttons to the layoutself.btnlayout.addWidget(self.UTF8ConvertorBtn) # 将按钮添加到功能按钮区布局updateButtonStyle(self,self.UTF8ConvertorBtn) # 更新按钮样式,该方法为作者创建,并非第三方库调用

UTF8ConvertorBtn按钮连接上了Cbtn_press_clicked方法,表示当该按钮被按下时,则调用Cbtn_press_clicked方法。同时我对按钮的样式做了修改,使用方法btnReleaseStyleA,因为要对按钮做批量相同的修改,因此集成到一个方法中去调用是常见的编程思想。

  	def Cbtn_press_clicked(self):updateButtonStyle(self,self.UTF8ConvertorBtn) # 更新按钮样式,该方法为作者创建,非第三方库调用self.stacklayout.setCurrentIndex(0) # 将当前stack布局设置为第一个抽屉

setCurrentIndex方法的意思是,stacklayout所占据的这一片区域,可以随意切换成被它add了的widget,它就像一个抽屉一样,抽屉的大小固定,但是这个固定的大小所展示的内容是由你抽出第几层决定。就比如参数为0,则抽出的是第1个抽屉,这个抽屉是一个widget,这个widget可以套一个layout,其中放各种各样的组件。同理,参数为1,则表示抽出第2个抽屉,则stacklayout所占据的这一片区域就会切换成第2个抽屉的样子。

4.4 UI初始化

    def initUI(self):#---------------- create Layout we needed ----------------------------self.Mainlayout = QHBoxLayout() # 主窗口self.Primarylayout = QVBoxLayout() # 功能区布局self.btnlayout = QVBoxLayout() # 功能按钮区布局#---------------- create Layout we needed ----------------------------#---------------- there has more btn but unshowing -------------------# set the convertor buttonsself.UTF8ConvertorBtn = QPushButton("UTF-8 转换") # 创建按钮对象btnReleaseStyleA(self.UTF8ConvertorBtn) # 修改按钮样式,该方法为作者创建,并非第三方库调用self.UTF8ConvertorBtn.clicked.connect(self.Cbtn_press_clicked) # 为按钮连接触发事件,该事件会切换stack# add the buttons to the layoutself.btnlayout.addWidget(self.UTF8ConvertorBtn) # 将按钮添加到功能按钮区布局updateButtonStyle(self,self.UTF8ConvertorBtn) # 更新按钮样式,该方法为作者创建,并非第三方库调用#---------------- there has more btn but unshowing -------------------self.btnlayout.setAlignment(Qt.AlignTop) # 调整按钮区的各组件对齐方式为向上对齐,而非均匀分布#----------------- put the stack in function area --------------------widget = QWidget() # 创建一个widget,用于存放stack布局widget.setLayout(self.stacklayout) # 将stack布局放到widget中self.Primarylayout.addWidget(widget) # 将widget放到功能区布局中,至此stack在功能区中进行切换#----------------- put the stack in function area --------------------#---------------------- create log area ------------------------------self.Consolelayout = QVBoxLayout() # 创建日志区布局self.consoleedit = QTextEdit() # 创建日志编辑文本框self.consoleedit.setReadOnly(True) # 文本框设置为只读TextEditStyle(self.consoleedit) # 修改文本框样式, 该方法为作者创建,并非第三方库调用self.consoleedit.verticalScrollBar().setPageStep(100) # 修改滚动条步长self.Consolelayout.addWidget(self.consoleedit) # 添加文本框到日志区布局中#---------------------- create log area ------------------------------#------------------ put the layouts in main layout -------------------self.Mainlayout.addLayout(self.btnlayout,stretch=1) # 将按钮布局添加到主布局中self.Vline = QFrame(self) # 添加细线 将按钮区与功能区分隔开self.Vline.setFrameShape(QFrame.VLine) # 优化细线self.Vline.setFrameShadow(QFrame.Raised) # 使细线具有凸起的立体感self.Vline.setLineWidth(3) # 设置细线外部粗细self.Vline.setMidLineWidth(1) # 设置细线内部粗细self.Mainlayout.addWidget(self.Vline) # 将细线添加至主布局self.Mainlayout.addLayout(self.Primarylayout,stretch=4) # 将功能区添加至主布局中self.Mainlayout.addLayout(self.Consolelayout,stretch=2) # 将日志区添加至主布局中# add the layout to the windowself.setLayout(self.Mainlayout) # 将主窗口的布局设置为主布局#------------------ put the layouts in main layout -------------------

4.5 结语

到目前为止,我们脚本工具集合包已经具备了初步的大致框架,三大区块已经被划分出来了,接下来的工作将重点放在要开发哪些功能,如何实现这些功能,以及这些功能的UI页面布局。这个系列将会持续更新,动手能力强的小伙伴可以根据路线自己实操一遍,后续我也会将完整代码开源带GitHub上(等系类差不多结束的时候),同时系列文章也会同步更新到我的个人博客中,如果本系列真的帮助到你,请关注本频道,并给我的CSDN 点赞收藏 QAQ,感激不尽!

如有任何疑问,欢迎CSDN私信我或发邮件到707973090@qq.com,在我看到时会第一时间回复!

相关文章:

PyQt5实战——操作台打印重定向,主界面以及stacklayout使用(四)

个人博客:苏三有春的博客 系类往期文章: PyQt5实战——多脚本集合包,前言与环境配置(一) PyQt5实战——多脚本集合包,UI以及工程布局(二) PyQt5实战——多脚本集合包,程序…...

React + Vite + TypeScript + React router项目搭建教程

一、创建项目 运行项目 二、目录结构 项目目录: ├─node_modules //第三方依赖 ├─public //静态资源(不参与打包) └─src├─assets //静态资源├─components //组件├─config //配置├─http //请求方法封装├─layout //页面…...

【ShuQiHere】️ 如何启用 SSH 服务

🛠️ 如何启用 SSH 服务 目录 基础概念 🌱检查是否已安装 SSH 服务 🔍在不同操作系统上安装 SSH 服务 💻 LinuxWindows 11macOS 启动和启用 SSH 服务 🚀配置防火墙以允许 SSH 连接 🔥配置 SSH 服务&#…...

【自动化测试】APP UI 自动化(安卓)-本地环境搭建

一、软件准备及版本介绍 软件版本JAVA-SDK1.8.0_181 python 3.10.10 Android SDK Tools 下最新版本即可,无特殊要求 PyCharm 2023.3.5(下最新版本即可,无特殊要求) 二、安装步骤及环境变量配置 2.1 Java安装及配置 1&am…...

java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)

项目简介 基于Bootstrap的常州地方旅游管理系统的设计与实现有下功能: 基于Bootstrap的常州地方旅游管理系统的设计与实现的主要使用者分为用户功能模块和管理员功能模块两大部分,用户可查看景点信息、景点资讯等,注册登录后可进行景点订票…...

《机甲崛起》

第一章:觉醒 在遥远的未来,地球的面貌已被人类科技彻底改变。蓝天被高耸的摩天大楼和闪烁的飞行器撕裂,城市的光辉仿佛能照亮整个星球。然而,繁华背后隐藏着深重的危机:生态环境的恶化、资源的匮乏,已成为…...

Windows10:Linux Reader

Linux Reader Access files and folders on Ext, UFS, HFS, ReiserFS, or APFS file systems from Windows DiskInternals 发布的 Linux Reader 是一款能在 Windows 系统环境下读取 Linux 分区文件的免费软件,提供了资源管理器式的浏览模式。它使用只读模式挂载 L…...

一、k8s快速入门之学习Kubernetes组件基础

一、三个容器管理器平台 Apache MESOS 开源的分布式资源管理框架,被推特选为基础平台,2019年推特换位k8s,MESOS最新版可以在MESOS上管理k8sDOCKER SWARM docker总部发行的,实现docker的集群方案,和docker捆版一起&…...

PostgreSQL 到 PostgreSQL 数据迁移同步

简述 PostgreSQL 是一个历史悠久且广泛使用的数据库,不仅具备标准的关系型数据库能力,还具有相当不错的复杂 SQL 执行能力。用户常常会将 PostgreSQL 应用于在线事务型业务,以及部分数据分析工作,所以 PostgreSQL 到 PostgreSQL …...

RestTemplate 常用方法(提供了多种方法来发送 HTTP 请求)

RestTemplate 是 Spring 框架中用于同步客户端 HTTP 请求的一个类,它提供了多种方法来发送 HTTP 请求。以下是一些常用的 RestTemplate 方法及其代码案例: 1.postForObject() 该方法用于发送 POST 请求,并期望返回一个对象。以下是一个使用…...

常量和变量

常量 常量是指在程序中使用的一些具体的数、字符。在程序运行过程中,其值不能被更改。如123,145.88,m,TRUE等。常量,用于记录程序中不可更改的数据。 分类 1、整型常量,表示整数的常量。 表示形式:   1)十进制形…...

Go语言的使用

在安装Go和配置镜像时,可以根据操作系统和网络环境来选择适合的步骤。以下是详细的安装步骤和镜像配置: 1. 安装Go 1.1 通过官方下载 访问 Go的官方下载页面 下载适合操作系统的安装包(Windows、macOS 或 Linux)。安装包下载完…...

详解CRC校验原理以及FPGA实现

文章目录 一、什么是CRC校验?二、实现CRC校验原理以及步骤2.1 用多项式表示二元码数据2.2 选择一个生成多项式作为校验2.3 计算CRC校验码 三、CRC判断数据是否错误的原理以及步骤3.1 将收到的数据与生成多项式求余3.2 数据发生错误再进行CRC校验判断 四、FPGA实现CR…...

企业如何通过架构蓝图实现数字化转型

数字化转型的关键——架构蓝图的力量 在当今的商业世界,数字化转型已经不再是一个选择,而是企业生存与发展不可回避的战略行动。企业希望通过数字化提高效率、增强灵活性,并为客户提供更好的体验。然而,数字化转型不仅仅涉及技术…...

React第十三章(useTransition)

useTransition useTransition 是 React 18 中引入的一个 Hook,用于管理 UI 中的过渡状态,特别是在处理长时间运行的状态更新时。它允许你将某些更新标记为“过渡”状态,这样 React 可以优先处理更重要的更新,比如用户输入&#x…...

IDEA使用Maven Helper查看整个项目的jar冲突

在插件市场安装Maven Helper,安装好后,重启IDEA;双击打开可能存在jar冲突的pom文件;在右侧面板查看冲突,text是引入的依赖明细,点击Dependecy Analyzer选项卡即可查看冲突的jar。...

uniapp项目 存储数据到手机本地

打开manifest.json&#xff0c;在App权限配置中&#xff0c;添加读取和写入的权限 <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...

景联文科技医疗数据处理平台:强化医疗数据标注与管理,推动医疗数字化新篇章

随着医疗科技快速进步与广泛应用&#xff0c;医疗信息的规模正在迅速扩张&#xff0c;如何有效管理这些医疗数据成为了关键议题。 医疗数据不仅包括传统的纸质病历&#xff0c;还有电子病历、实验室检测结果、医学影像等多样化的数字信息。为确保这些数据能为临床决策、科研分析…...

vue使用高德地图实现轨迹显隐

<template><div><el-button type"primary" click"pathShowOrHide">轨迹显/隐</el-button><div id"container" /></div> </template><script> import AMapLoader from amap/amap-jsapi-loaderex…...

Maven(20) 如何使用Maven进行版本管理?

Maven提供了一套强大的版本管理机制&#xff0c;允许开发者管理项目的版本号&#xff0c;并在不同的版本之间进行升级和降级。以下是如何使用Maven进行版本管理的详细步骤和代码示例&#xff1a; 步骤 1: 定义项目版本 在pom.xml文件中&#xff0c;你需要定义项目的版本号。版…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...