Skip to content

Commit 4775bb7

Browse files
committed
Enhance CenterWidget
实现选项设置成功对中央控件界面的影响; 增加选项设置成功后状态栏提示; 实现选项设置错误对中央控件界面的影响与警告; 修复 `PackagingTask` 中的一些错误;
1 parent 30f6f6e commit 4775bb7

3 files changed

Lines changed: 131 additions & 61 deletions

File tree

src/py2exe_gui/Core/packaging_task.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self, parent: Optional[QtCore.QObject] = None) -> None:
2929

3030
def handle_option(self, option: tuple[str, str]):
3131
"""
32-
处理用户在界面选择的打包选项 \n
32+
处理用户在界面选择的打包选项,进行有效性验证并保存 \n
3333
:param option: 选项
3434
"""
3535

@@ -39,22 +39,32 @@ def handle_option(self, option: tuple[str, str]):
3939
if arg_key == "script_path":
4040
script_path = Path(arg_value)
4141
if FilePathValidator.validate_script(script_path):
42-
self.out_name = script_path.stem # 输出名默认与脚本名相同
42+
self.script_path = script_path
4343
self.ready_to_pack.emit(True)
4444
self.option_set.emit(option)
45+
self.out_name = script_path.stem # 输出名默认与脚本名相同
46+
self.option_set.emit(("out_name", self.out_name))
4547
else:
4648
self.ready_to_pack.emit(False)
47-
self.option_error.emit("script_path")
49+
self.option_error.emit(arg_key)
50+
# self.option_error.emit(arg_key) # 测试用!
51+
4852
elif arg_key == "icon_path":
49-
self.option_set.emit(option)
50-
elif arg_key == "FD":
51-
self.option_set.emit(option)
52-
elif arg_key == "console":
53-
self.option_set.emit(option)
53+
icon_path = Path(arg_value)
54+
if FilePathValidator.validate_icon(icon_path):
55+
self.icon_path = icon_path
56+
self.option_set.emit(option)
57+
else:
58+
self.option_error.emit(arg_key)
59+
# self.option_error.emit(arg_key) # 测试用!
60+
5461
elif arg_key == "out_name":
5562
self.out_name = arg_value
5663
self.option_set.emit(option)
5764

65+
else:
66+
self.option_set.emit(option)
67+
5868
def write_to_file(self):
5969
"""
6070
将打包任务保存至文件

src/py2exe_gui/Core/validators.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ def validate_script(cls, script_path: Union[str, Path]) -> bool:
2323
else:
2424
return False
2525

26+
@classmethod
27+
def validate_icon(cls, icon_path: Union[str, Path]) -> bool:
28+
"""
29+
验证图标路径是否有效 \n
30+
:param icon_path: 图标路径
31+
"""
32+
33+
path = Path(icon_path)
34+
# TODO 完善验证方法
35+
if path.exists() and path.is_file():
36+
return True
37+
else:
38+
return False
39+
2640

2741
class InterpreterValidator:
2842
"""

src/py2exe_gui/Widgets/center_widget.py

Lines changed: 99 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from pathlib import Path
2+
13
from PySide6 import QtCore
24
from PySide6.QtWidgets import (
35
QButtonGroup,
@@ -6,6 +8,7 @@
68
QLabel,
79
QLineEdit,
810
QMainWindow,
11+
QMessageBox,
912
QPushButton,
1013
QRadioButton,
1114
QVBoxLayout,
@@ -15,6 +18,8 @@
1518
from .arguments_browser import ArgumentsBrowser
1619
from .dialog_widgets import IconFileDlg, ScriptFileDlg
1720

21+
# TODO 使用字适当数据结构管理选项列表
22+
1823

1924
class CenterWidget(QWidget):
2025
"""
@@ -38,8 +43,8 @@ def __init__(self, parent: QMainWindow = None) -> None:
3843
self.script_path_le = QLineEdit()
3944

4045
# 打包后输出的项目名称
41-
self.name_label = QLabel()
42-
self.name_le = QLineEdit()
46+
self.project_name_label = QLabel()
47+
self.project_name_le = QLineEdit()
4348

4449
# 输出至单目录/单文件
4550
self.fd_label = QLabel()
@@ -71,13 +76,13 @@ def setup_ui(self) -> None:
7176
设置各种控件的属性 \n
7277
"""
7378

74-
self.script_path_label.setText("脚本路径:")
79+
self.script_path_label.setText("待打包脚本:")
7580
self.script_path_le.setReadOnly(True)
7681
self.script_path_le.setPlaceholderText("Python入口文件路径")
7782
self.script_browse_btn.setText("浏览")
7883

79-
self.name_label.setText("输出名称:")
80-
self.name_le.setPlaceholderText("打包的应用程序名称")
84+
self.project_name_label.setText("项目名称:")
85+
self.project_name_le.setPlaceholderText("打包的应用程序名称")
8186

8287
self.fd_label.setText("单文件/单目录:")
8388
self.one_dir_btn.setText("打包至单个目录")
@@ -86,7 +91,7 @@ def setup_ui(self) -> None:
8691
self.fd_group.addButton(self.one_dir_btn, 0)
8792
self.fd_group.addButton(self.one_file_btn, 1)
8893

89-
self.icon_path_label.setText("图标路径:")
94+
self.icon_path_label.setText("应用图标:")
9095
self.icon_path_le.setReadOnly(True)
9196
self.icon_path_le.setPlaceholderText("图标文件路径")
9297
self.icon_browse_btn.setText("浏览")
@@ -112,25 +117,17 @@ def script_file_selected(file_path: str) -> None:
112117
:param file_path: 脚本文件路径
113118
"""
114119

115-
# TODO 验证有效性、将脚本名作为默认app名
116-
self.script_path_le.setText(file_path)
117-
self.parent().statusBar().showMessage(f"打开脚本路径:{file_path}")
118120
self.option_selected.emit(("script_path", file_path))
119121

120-
self.script_browse_btn.clicked.connect(self.script_file_dlg.open) # type: ignore
121-
self.script_file_dlg.fileSelected.connect(script_file_selected) # type: ignore
122-
123-
# FIXME 默认输出程序名称与入口脚本名称相同
124122
@QtCore.Slot(str)
125123
def project_name_selected() -> None:
126124
"""
127125
输出程序名称完成输入的槽 \n
128126
"""
129127

130-
pro_name: str = self.name_le.text()
131-
self.option_selected.emit(("out_name", pro_name))
132-
133-
self.name_le.editingFinished.connect(project_name_selected) # type: ignore
128+
project_name: str = self.project_name_le.text()
129+
self.option_selected.emit(("out_name", project_name))
130+
self.parent().statusBar().showMessage(f"已将项目名设置为:{project_name}")
134131

135132
@QtCore.Slot(int)
136133
def one_fd_selected(btn_id: int) -> None:
@@ -141,10 +138,10 @@ def one_fd_selected(btn_id: int) -> None:
141138

142139
if btn_id == 0:
143140
self.option_selected.emit(("FD", "One Dir"))
141+
self.parent().statusBar().showMessage("将打包至单个目录中")
144142
elif btn_id == 1:
145143
self.option_selected.emit(("FD", "One File"))
146-
147-
self.fd_group.idClicked.connect(one_fd_selected) # type: ignore
144+
self.parent().statusBar().showMessage("将打包至单个文件中")
148145

149146
@QtCore.Slot(bool)
150147
def console_selected(console: bool) -> None:
@@ -155,10 +152,10 @@ def console_selected(console: bool) -> None:
155152

156153
if console:
157154
self.option_selected.emit(("console", "console"))
155+
self.parent().statusBar().showMessage("将为打包程序的 stdio 启用终端")
158156
else:
159157
self.option_selected.emit(("console", "windowed"))
160-
161-
self.console_checkbox.toggled.connect(console_selected) # type: ignore
158+
self.parent().statusBar().showMessage("不会为打包程序的 stdio 启用终端")
162159

163160
@QtCore.Slot(str)
164161
def icon_file_selected(file_path: str) -> None:
@@ -167,13 +164,90 @@ def icon_file_selected(file_path: str) -> None:
167164
:param file_path: 图标路径
168165
"""
169166

170-
self.icon_path_le.setText(file_path)
171-
self.parent().statusBar().showMessage(f"打开图标路径:{file_path}")
172167
self.option_selected.emit(("icon_path", file_path))
173168

169+
self.script_browse_btn.clicked.connect(self.script_file_dlg.open) # type: ignore
170+
self.script_file_dlg.fileSelected.connect(script_file_selected) # type: ignore
171+
self.project_name_le.editingFinished.connect(project_name_selected) # type: ignore
172+
self.fd_group.idClicked.connect(one_fd_selected) # type: ignore
173+
self.console_checkbox.toggled.connect(console_selected) # type: ignore
174174
self.icon_browse_btn.clicked.connect(self.icon_file_dlg.open) # type: ignore
175175
self.icon_file_dlg.fileSelected.connect(icon_file_selected) # type: ignore
176176

177+
@QtCore.Slot(tuple)
178+
def handle_option_set(self, option: tuple[str, str]) -> None:
179+
"""
180+
处理option_set信号的槽,根据已经成功设置的选项调整界面 \n
181+
:param option: 选项键值对
182+
"""
183+
184+
option_key, option_value = option
185+
186+
if option_key == "script_path":
187+
script_path = Path(option_value)
188+
self.script_path_le.setText(script_path.name)
189+
self.parent().statusBar().showMessage(
190+
f"打开脚本路径:{str(script_path.resolve())}"
191+
)
192+
193+
elif option_key == "icon_path":
194+
icon_path = Path(option_value)
195+
self.icon_path_le.setText(icon_path.name)
196+
self.parent().statusBar().showMessage(f"打开图标路径:{str(icon_path.resolve())}")
197+
198+
elif option_key == "out_name":
199+
self.project_name_le.setText(option_value)
200+
201+
@QtCore.Slot(str)
202+
def handle_option_error(self, option: str) -> None:
203+
"""
204+
处理option_error信号的槽,重置设置失败的选项对应的界面,并向用户发出警告 \n
205+
:param option: 选项
206+
"""
207+
208+
# 清空重置该项的输入控件,并弹出警告窗口,等待用户重新输入
209+
if option == "script_path":
210+
self.script_file_dlg.close()
211+
212+
# 警告对话框
213+
result = QMessageBox.critical(
214+
self.parent(),
215+
"错误",
216+
"选择的不是有效的Python脚本文件,请重新选择!",
217+
QMessageBox.Cancel,
218+
QMessageBox.Ok,
219+
)
220+
if result == QMessageBox.Cancel:
221+
self.script_path_le.clear()
222+
self.project_name_le.clear()
223+
elif result == QMessageBox.Ok:
224+
self.script_file_dlg.open() # FIXME 修复无法再次打开对话框的问题
225+
226+
elif option == "icon_path":
227+
self.icon_file_dlg.close()
228+
229+
# 警告对话框
230+
result = QMessageBox.critical(
231+
self.parent(),
232+
"错误",
233+
"选择的不是有效的图标文件,请重新选择!",
234+
QMessageBox.Cancel,
235+
QMessageBox.Ok,
236+
)
237+
if result == QMessageBox.Cancel:
238+
self.icon_path_le.clear()
239+
elif result == QMessageBox.Ok:
240+
self.icon_file_dlg.open() # FIXME 修复无法再次打开对话框的问题
241+
242+
@QtCore.Slot(bool)
243+
def handle_ready_to_pack(self, ready: bool) -> None:
244+
"""
245+
处理ready_to_pack信号的槽 \n
246+
:param ready: 是否可以进行打包
247+
"""
248+
249+
self.run_packaging_btn.setEnabled(ready)
250+
177251
def _set_layout(self) -> None:
178252
"""
179253
设置布局管理器 \n
@@ -185,8 +259,8 @@ def _set_layout(self) -> None:
185259
script_layout.addWidget(self.script_browse_btn, 1, 1)
186260

187261
name_layout = QVBoxLayout()
188-
name_layout.addWidget(self.name_label)
189-
name_layout.addWidget(self.name_le)
262+
name_layout.addWidget(self.project_name_label)
263+
name_layout.addWidget(self.project_name_le)
190264

191265
fd_layout = QGridLayout()
192266
fd_layout.addWidget(self.fd_label, 0, 0, 1, 2)
@@ -207,31 +281,3 @@ def _set_layout(self) -> None:
207281
main_layout.addWidget(self.pyinstaller_args_browser)
208282
main_layout.addWidget(self.run_packaging_btn)
209283
self.setLayout(main_layout)
210-
211-
@QtCore.Slot(tuple)
212-
def handle_option_set(self, option: tuple[str, str]) -> None:
213-
"""
214-
处理option_set信号的槽 \n
215-
:param option: 选项键值对
216-
"""
217-
218-
pass
219-
220-
@QtCore.Slot(str)
221-
def handle_option_error(self, option: str) -> None:
222-
"""
223-
处理option_error信号的槽 \n
224-
:param option: 选项
225-
"""
226-
227-
# 清空重置该项的输入控件,等待用户重新输入
228-
pass
229-
230-
@QtCore.Slot(bool)
231-
def handle_ready_to_pack(self, ready: bool) -> None:
232-
"""
233-
处理ready_to_pack信号的槽 \n
234-
:param ready: 是否可以进行打包
235-
"""
236-
237-
self.run_packaging_btn.setEnabled(ready)

0 commit comments

Comments
 (0)