Skip to content

Commit 077b36a

Browse files
committed
Update SubProcessTool
实现 `SubProcessTool` 中对子进程错误的处理; 改进 type hint; 其他微小优化;
1 parent 12b8254 commit 077b36a

2 files changed

Lines changed: 39 additions & 24 deletions

File tree

src/py2exe_gui/Core/packaging.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Packaging(QtCore.QObject):
1717
"""
1818

1919
# 自定义信号
20-
args_settled = QtCore.Signal(list)
20+
args_settled = QtCore.Signal(list) # 所有选项完成设置,直接将命令行参数传出
2121

2222
def __init__(self, parent: Optional[QtCore.QObject] = None) -> None:
2323
"""
@@ -29,7 +29,7 @@ def __init__(self, parent: Optional[QtCore.QObject] = None) -> None:
2929
self.args_dict: dict = dict.fromkeys(PyinstallerArgs, "")
3030
self._args: List[str] = []
3131
self._subprocess_working_dir: str = ""
32-
self.subprocess: SubProcessTool = SubProcessTool(self, program="pyinstaller")
32+
self.subprocess: SubProcessTool = SubProcessTool("pyinstaller", parent=self)
3333

3434
@QtCore.Slot(tuple)
3535
def set_pyinstaller_args(self, arg: tuple[PyinstallerArgs, str]) -> None:

src/py2exe_gui/Core/subprocess_tool.py

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,30 @@
55
from sys import getdefaultencoding
66
from typing import Optional, Sequence
77

8-
from PySide6 import QtCore
8+
from PySide6.QtCore import QIODeviceBase, QObject, QProcess, Signal
99

1010

11-
class SubProcessTool(QtCore.QObject):
11+
class SubProcessTool(QObject):
1212
"""
13-
辅助QProcess使用的工具类,将所有直接对子进程进行的操作都封装在此类中
13+
辅助QProcess使用的工具类,将所有直接对子进程进行的操作都封装在此类中 \n
1414
"""
1515

1616
# 自定义信号,参数为 tuple[output_type: int, output_text: str]
17-
output = QtCore.Signal(tuple)
17+
output = Signal(tuple)
1818

1919
# output_types
2020
STATE = 1
2121
STDOUT = 2
2222
STDERR = 3
23-
FINISHED = 4
23+
STARTED = 4
24+
FINISHED = 5
25+
ERROR = 6
2426

2527
def __init__(
2628
self,
27-
parent: Optional[QtCore.QObject] = None,
29+
program: str,
2830
*,
29-
program: str = "",
31+
parent: Optional[QObject] = None,
3032
arguments: Sequence[str] = (),
3133
working_directory: str = "./",
3234
) -> None:
@@ -42,22 +44,22 @@ def __init__(
4244
self.program: str = program
4345
self._arguments: Sequence[str] = arguments
4446
self._working_directory: str = working_directory
45-
self._process: Optional[QtCore.QProcess] = None
47+
self._process: Optional[QProcess] = None
4648
self.exit_code: int = 0
47-
self.exit_status: QtCore.QProcess.ExitStatus = QtCore.QProcess.NormalExit
49+
self.exit_status: QProcess.ExitStatus = QProcess.ExitStatus.NormalExit
4850

4951
def start_process(
5052
self,
5153
*,
52-
mode: QtCore.QIODeviceBase.OpenMode = QtCore.QIODeviceBase.OpenModeFlag.ReadWrite, # type: ignore
54+
mode: QIODeviceBase.OpenModeFlag = QIODeviceBase.OpenModeFlag.ReadWrite,
5355
) -> None:
5456
"""
5557
创建并启动子进程 \n
5658
:param mode: 设备打开的模式
5759
"""
5860

5961
if self._process is None: # 防止在子进程运行结束前重复启动
60-
self._process = QtCore.QProcess(self)
62+
self._process = QProcess(self)
6163

6264
self._process.stateChanged.connect(self._handle_state) # type: ignore
6365
self._process.readyReadStandardOutput.connect(self._handle_stdout) # type: ignore
@@ -112,9 +114,9 @@ def _process_started(self) -> None:
112114
处理子进程开始的槽 \n
113115
"""
114116

115-
pass
117+
self.output.emit((self.STARTED, "started"))
116118

117-
def _process_finished(self, code: int, status: QtCore.QProcess.ExitStatus) -> None:
119+
def _process_finished(self, code: int, status: QProcess.ExitStatus) -> None:
118120
"""
119121
处理子进程结束的槽 \n
120122
:param code: 退出码
@@ -133,7 +135,7 @@ def _handle_stdout(self) -> None:
133135

134136
if self._process:
135137
data = self._process.readAllStandardOutput()
136-
stdout = bytes(data).decode(getdefaultencoding()) # 将QByteArray转为str
138+
stdout = bytes(data).decode(getdefaultencoding()) # type: ignore
137139
self.output.emit((self.STDOUT, stdout))
138140

139141
def _handle_stderr(self) -> None:
@@ -143,27 +145,40 @@ def _handle_stderr(self) -> None:
143145

144146
if self._process:
145147
data = self._process.readAllStandardError()
146-
stderr = bytes(data).decode(getdefaultencoding()) # 将QByteArray转为str
148+
stderr = bytes(data).decode(getdefaultencoding()) # type: ignore
147149
self.output.emit((self.STDERR, stderr))
148150

149-
def _handle_state(self, state: QtCore.QProcess.ProcessState) -> None:
151+
def _handle_state(self, state: QProcess.ProcessState) -> None:
150152
"""
151153
将子进程运行状态转换为易读形式 \n
152154
:param state: 进程运行状态
153155
"""
154156

155157
states = {
156-
QtCore.QProcess.NotRunning: "非运行",
157-
QtCore.QProcess.Starting: "启动中……",
158-
QtCore.QProcess.Running: "正在运行中……",
158+
QProcess.ProcessState.NotRunning: "非运行",
159+
QProcess.ProcessState.Starting: "启动中……",
160+
QProcess.ProcessState.Running: "正在运行中……",
159161
}
160162
state_name = states[state]
161163
self.output.emit((self.STATE, state_name))
162164

163-
def _handle_error(self, error: QtCore.QProcess.ProcessError) -> None:
165+
def _handle_error(self, error: QProcess.ProcessError) -> None:
164166
"""
165167
处理子进程错误 \n
166-
:param error: 子进程错误
168+
:param error: 子进程错误类型
167169
"""
168170

169-
pass
171+
process_error = {
172+
QProcess.ProcessError.FailedToStart: "进程启动失败",
173+
QProcess.ProcessError.Crashed: "进程崩溃",
174+
QProcess.ProcessError.Timedout: "超时",
175+
QProcess.ProcessError.WriteError: "写入错误",
176+
QProcess.ProcessError.ReadError: "读取错误",
177+
QProcess.ProcessError.UnknownError: "未知错误",
178+
}
179+
error_type = process_error[error]
180+
181+
if self._process:
182+
self.abort_process(0)
183+
self.output.emit((self.ERROR, error_type))
184+
self._process = None

0 commit comments

Comments
 (0)