【Python_PySide6学习笔记(四十)】基于subprocess实现应用程序的重启并传递参数

news/2024/12/11 21:52:53/

基于 subprocess 实现应用程序的重启并传递参数

    • 基于 subprocess 实现应用程序的重启并传递参数
    • 前言
    • 1、subprocess 标准库
    • 2、重启逻辑
      • 2.1 定义新的参数列表
      • 2.2 当前 Python 解释器的路径
      • 2.3 获取当前脚本的绝对路径
      • 2.4 构造完整的命令行列表
      • 2.5 启动新的 Python 进程
      • 2.6 退出当前应用程序
    • 3、代码示例

subprocess__1">基于 subprocess 实现应用程序的重启并传递参数

前言

在开发桌面应用程序时,有时需要实现应用程序的重启功能,并在重启过程中传递特定的参数。本学习笔记将深入探讨如何使用 Python 的 subprocess 库来实现这一功能。我们将通过 PySide6 框架构建一个示例应用程序,展示如何在不丢失当前状态的前提下,优雅地重启应用程序并传递所需参数。这一技巧对于需要动态更新配置或重新加载资源的桌面应用尤为重要。通过本文,将学会如何结合 subprocess 库与 PySide6 ,实现应用程序的灵活重启与参数传递。

在这里插入图片描述

subprocess__9">1、subprocess 标准库

subprocess 库 是 Python 中用于创建和管理子进程的标准库,它提供了一个强大而灵活的接口,使得用户可以在 Python 中启动新的进程、连接它们的输入和输出,并与它们进行交互。

1.1 主要功能

  • 运行外部命令subprocess 库允许用户运行任何在命令行下可以运行的命令或程序;
  • 交互式进程通信:用户可以启动一个新的进程,并通过其标准输入、输出和错误管道与之交互。例如,可以发送数据给进程的标准输入,或者读取进程的标准输出和错误输出;
  • 管道和重定向subprocess 库支持创建管道,将一个进程的输出重定向到另一个进程的输入,或者将进程的输出重定向到一个文件;
  • 进程管理:用户可以监控进程的状态,等待进程结束,或者终止进程。

1.2 主要函数

subprocessrun_19">1.2.1 subprocess.run()
  • 功能:运行命令并等待其完成;

  • 参数:包括:

    参数作用
    args要执行的命令和参数
    stdin子进程的标准输入
    stdout子进程的标准输出
    stderr子进程的标准错误
    capture_output是否捕获子进程的标准输出和标准错误
    shell是否在一个shell中执行命令
    cwd子进程的工作目录
    timeout子进程的超时时间
    check当子进程返回非零退出状态时是否引发异常
  • 返回值:返回一个 CompletedProcess 实例,包含执行结果、返回内容等信息。

subprocessPopen_36">1.2.2 subprocess.Popen()
  • 功能:创建并管理子进程,允许更细粒度地控制子进程的输入、输出和行为;

  • 参数:与 subprocess.run() 类似,但更为详细和灵活;

  • 方法:包括:

    函数作用
    poll()检查子进程是否已结束
    communicate()与子进程进行交互
    send_signal()向子进程发送信号
    terminate()终止子进程
    kill()强制杀死子进程
subprocesscheck_call_51">1.2.3 subprocess.check_call()
  • 功能:运行命令并检查其退出状态。如果命令执行失败(即退出状态码不为0),则引发 CalledProcessError 异常。
  • 参数:与 subprocess.run() 类似。
subprocesscheck_output_56">1.2.4 subprocess.check_output()
  • 功能:运行命令并返回其输出。如果命令执行失败,则引发异常。
  • 参数:与 subprocess.run() 类似。

2、重启逻辑

2.1 定义新的参数列表

根据需求自定义新参数列表

python">        # 定义要传递的新参数new_args = ['参数1', '参数2', '参数3']

2.2 当前 Python 解释器的路径

使用 sys.executable 获取当前 Python 解释器的路径

python">        python_executable = sys.executable

2.3 获取当前脚本的绝对路径

使用 os.path.abspath(__file__) 获取当前脚本的绝对路径

python">        script_path = os.path.abspath(__file__)

2.4 构造完整的命令行列表

构造完整的命令行列表 command,包括 Python 解释器、脚本路径和新参数

python">        # 构造命令以重新启动应用程序(获取Python解释器及脚本文件)python_executable = sys.executablescript_path = os.path.abspath(__file__)command = [python_executable, script_path] + new_args

2.5 启动新的 Python 进程

使用 subprocess.Popen 启动新的 Python 进程来运行脚本并传递参数

python">        # 重启应用程序subprocess.Popen(command)

注意:如果程序已经打包为 .exe 文件,则需要使用 sys.executable 获取执行的 exe 文件

python">        # 在打包后的环境中,sys.executable 将指向 .exe 文件executable_path = sys.executable# 构造命令来重启应用程序command = [executable_path] + new_args# 重启应用程序subprocess.Popen(command)

2.6 退出当前应用程序

调用 sys.exit() 退出当前应用程序

python">        # 退出当前应用程序sys.exit()

3、代码示例

python">import sys
import os
import subprocess
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButtonclass RestartableApp(QWidget):def __init__(self, args=None):super().__init__()# 重启按键self.restart_button = None# 显示标签self.arg_label = Noneself.setFixedSize(300, 100)self.initUI(args)def initUI(self, args):self.setWindowTitle('PySide6应用重启并传参')self.setLayout(QVBoxLayout())# 需要显示的参数if args:arg_str = ' '.join(args)else:arg_str = '没有参数'self.arg_label = QPushButton(f'参数: {arg_str}')self.arg_label.setDisabled(True)self.layout().addWidget(self.arg_label)self.restart_button = QPushButton('重启并传递参数')self.restart_button.clicked.connect(self.restart_with_args)self.layout().addWidget(self.restart_button)@staticmethoddef restart_with_args():# 定义要传递的新参数new_args = ['参数1', '参数2', '参数3']# 构造命令以重新启动应用程序(获取Python解释器及脚本文件)python_executable = sys.executablescript_path = os.path.abspath(__file__)command = [python_executable, script_path] + new_args# 重启应用程序subprocess.Popen(command)# <editor-fold desc="如果程序已打包,则指向exe文件"># # 在打包后的环境中,sys.executable 将指向 .exe 文件# executable_path = sys.executable# # 构造命令来重启应用程序# command = [executable_path] + new_args# # 重启应用程序# subprocess.Popen(command)# </editor-fold># 退出当前应用程序sys.exit()if __name__ == '__main__':# 获取传递给入口文件的参数(不包括入口文件名称)passed_args = sys.argv[1:]app = QApplication(sys.argv)window = RestartableApp(passed_args)window.show()sys.exit(app.exec())

http://www.ppmy.cn/news/1554323.html

相关文章

jmeter调整字号无法生效?

调整之前如上图&#xff0c;字体非常小&#xff0c;哪怕我设置的字号是48 查阅了资料&#xff0c;试了几次&#xff0c;解决办法如下&#xff1a; 用编辑器打开jmeter.bat 在echo off的下一行添加以下代码 set JVM_ARGS%JVM_ARGS% -Dswing.plaf.metal.controlFontDialog-20…

go返回多个errors

起因 有时候大家可能需要返回多个errors的场景&#xff0c;所以这个时候可能就会考虑如何实现、怎么实现比较好 实现 package mainimport ("errors""fmt" )func main() {errs : retErrors("hello,world")fmt.Println(errs) }func retErrors(t…

OpenTK为SkiaSharp在.NET 环境下提供OpenGL支持,使其进行高效的2D渲染

前言 在 .NET 环境下&#xff0c;OpenTK 为 SkiaSharp 提供了 OpenGL 支持&#xff0c;使得 SkiaSharp 能够利用 OpenGL 进行高效的 2D 渲染。这种结合能够充分发挥 GPU 的加速能力&#xff0c;从而提升渲染性能&#xff0c;尤其是在需要进行复杂图形处理或频繁更新的应用中&a…

MR30分布式 I/O 模块助力 CNC 设备产能飞跃

背景分析 在现代制造业中&#xff0c;CNC 设备扮演着极为关键的角色。然而&#xff0c;CNC 设备在运行过程中也存在着诸多痛点。传统的 CNC 设备往往在控制与通信方面存在局限&#xff0c;其内部的 I/O 系统大多采用集中式架构。这种架构下&#xff0c;一旦需要处理大量的输入输…

MVC基础——市场管理系统(三)Clean Architecture

文章目录 项目地址五、Clean Architecture5.1 user cage driven5.1.1创建CoreBusiness 5.2 创建UseCases5.2.1 创建CategoriesUseCases1. 创建VeiwCategoriesUseCase获取所有Cagegory 5.2.2. 实现ICategoryRepository接口3. 实现获取所有Category的方法4. 实现获取一个Cagegory…

k8s-容器运行时接口分析

1、为了什么需要 CRI &#xff1f; 在 k8s v1.5 之前&#xff0c;Docker 作为第一代的容器运行时&#xff0c; kubelet 通过内嵌其中的 DockerShim 操作 Docker API 来操作容器。在 Kubernetes 1.5 中引入了 CRI&#xff0c;可以解耦了kubelet与容器运行时&#xff0c;该插件接…

qiankun学习记录

什么是微前端 微前端是指存在于浏览器中的微服务&#xff0c;其借鉴了微服务的架构理念&#xff0c;将微服务的概念扩展到了前端。 如果对微服务的概念比较陌生的话&#xff0c;可以简单的理解为微前端就是将一个大型的前端应用拆分成多个模块&#xff0c;每个微前端模块可以…

Linux: glibc: 频繁调用new/delete会不会导致内存的碎片

最近同事问了一个问题:频繁调用new/delete会不会导致内存的碎片。 下面是我想到的一些回答, glibc的内存处理机制,是在释放的时候会自动将小块内存整合成大块内存,为接下来满足大块的需求的可能。而且程序也不是一直占着内存不释放(如果是一直不释放,要考虑是不是内存泄漏…