From 55e716b0d3e732c8ef2cdd8a3132c5ff7e41f216 Mon Sep 17 00:00:00 2001 From: muzing Date: Wed, 7 Sep 2022 20:55:05 +0800 Subject: [PATCH] Fix subprocess bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复子进程运行结束前可以被新启动的同类子进程打断的问题; 修复在非默认utf-8平台下QByteArray解码字符串错误的问题; --- src/py2exe-gui/Core/packaging.py | 8 +++++--- src/py2exe-gui/Core/subprocess_tool.py | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/py2exe-gui/Core/packaging.py b/src/py2exe-gui/Core/packaging.py index 5e1fc36..2c7de33 100644 --- a/src/py2exe-gui/Core/packaging.py +++ b/src/py2exe-gui/Core/packaging.py @@ -27,7 +27,7 @@ class Packaging(QObject): def get_pyinstaller_args(self, arg: tuple[str, str]) -> None: """ - 解析传递来的PyInstaller运行参数,并以正确的顺序添加至命令参数字典 \n + 解析传递来的PyInstaller运行参数,并添加至命令参数字典 \n :param arg: 运行参数 """ @@ -38,7 +38,8 @@ class Packaging(QObject): def set_pyinstaller_args(self) -> None: """ - 将命令参数字典中的参数按顺序添加到命令参数列表中 + 将命令参数字典中的参数按顺序添加到命令参数列表中 \n + :return: None """ self._args = [] # 避免重复添加 @@ -66,6 +67,7 @@ class Packaging(QObject): :return: None """ - self.subprocess = QSubProcessTool() + if self.subprocess is None: # 确保只在首次调用时实例化一个QSubProcess对象 + self.subprocess = QSubProcessTool() self.subprocess.output.connect(lambda val: print(val)) # 测试用 self.subprocess.start_process("pyinstaller", self._args) diff --git a/src/py2exe-gui/Core/subprocess_tool.py b/src/py2exe-gui/Core/subprocess_tool.py index 8de91d5..6441361 100644 --- a/src/py2exe-gui/Core/subprocess_tool.py +++ b/src/py2exe-gui/Core/subprocess_tool.py @@ -1,3 +1,4 @@ +from sys import getdefaultencoding from typing import Optional, Sequence from PySide6 import QtCore @@ -21,7 +22,7 @@ class QSubProcessTool(QtCore.QObject): def start_process(self, program: str, arguments: Sequence[str]) -> None: """ - 启动子进程 \n + 使用给定参数启动指定子进程 \n :param program: 子进程命令 :param arguments: 子进程参数 :return: None @@ -30,18 +31,27 @@ class QSubProcessTool(QtCore.QObject): if self.process is None: # 防止在子进程运行结束前重复启动 self.process = QtCore.QProcess() + self.process.stateChanged.connect(self._handle_state) # type: ignore self.process.readyReadStandardOutput.connect(self._handle_stdout) # type: ignore self.process.readyReadStandardError.connect(self._handle_stderr) # type: ignore - self.process.stateChanged.connect(self._handle_state) # type: ignore + self.process.started.connect(self._process_started) # type: ignore self.process.finished.connect(self._process_finished) # type: ignore self.process.start(program, arguments) + def _process_started(self) -> None: + """ + 处理子进程的槽 \n + :return: None + """ + pass + def _process_finished(self) -> None: """ 处理子进程的槽 \n :return: None """ + self.output.emit((self.FINISHED, "Subprocess finished.")) self.process = None @@ -53,7 +63,7 @@ class QSubProcessTool(QtCore.QObject): if self.process: data = self.process.readAllStandardOutput() - stdout = bytes(data).decode("utf8") + stdout = bytes(data).decode(getdefaultencoding()) self.output.emit((self.STDOUT, stdout)) def _handle_stderr(self) -> None: @@ -64,7 +74,7 @@ class QSubProcessTool(QtCore.QObject): if self.process: data = self.process.readAllStandardError() - stderr = bytes(data).decode("utf8") + stderr = bytes(data).decode(getdefaultencoding()) self.output.emit((self.STDERR, stderr)) def _handle_state(self, state: QtCore.QProcess.ProcessState) -> None: