Skip to content

Commit b257c35

Browse files
committed
Add --hidden-import feature
添加“添加隐式导入”功能;
1 parent 7e94271 commit b257c35

6 files changed

Lines changed: 116 additions & 72 deletions

File tree

src/py2exe_gui/Constants/packaging_constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ class PyInstOpt(enum.IntFlag):
2121
out_name = enum.auto()
2222
add_data = enum.auto()
2323
add_binary = enum.auto()
24+
hidden_import = enum.auto()
2425
clean = enum.auto()

src/py2exe_gui/Core/packaging.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,31 @@ def _add_pyinstaller_args(self) -> None:
5959
self._args = [] # 避免重复添加
6060

6161
self._args.append(self.args_dict[PyInstOpt.script_path])
62+
6263
if self.args_dict[PyInstOpt.icon_path]:
6364
self._args.extend(["--icon", self.args_dict[PyInstOpt.icon_path]])
65+
6466
if self.args_dict[PyInstOpt.add_data]:
6567
for item in self.args_dict[PyInstOpt.add_data]:
6668
self._args.extend(["--add-data", f"{item[0]}:{item[1]}"])
69+
6770
if self.args_dict[PyInstOpt.add_binary]:
6871
for item in self.args_dict[PyInstOpt.add_binary]:
6972
self._args.extend(["--add-binary", f"{item[0]}:{item[1]}"])
73+
7074
if self.args_dict[PyInstOpt.FD]:
7175
self._args.append(self.args_dict[PyInstOpt.FD])
76+
7277
if self.args_dict[PyInstOpt.console]:
7378
self._args.append(self.args_dict[PyInstOpt.console])
79+
80+
if self.args_dict[PyInstOpt.hidden_import]:
81+
for item in self.args_dict[PyInstOpt.hidden_import]:
82+
self._args.extend(["--hidden-import", item])
83+
7484
if self.args_dict[PyInstOpt.out_name]:
7585
self._args.extend(["--name", self.args_dict[PyInstOpt.out_name]])
86+
7687
if self.args_dict[PyInstOpt.clean]:
7788
self._args.append(self.args_dict[PyInstOpt.clean])
7889

src/py2exe_gui/Core/packaging_task.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def __init__(self, parent: Optional[QtCore.QObject] = None) -> None:
3838
PyInstOpt.out_name: None,
3939
PyInstOpt.FD: None,
4040
PyInstOpt.console: None,
41+
PyInstOpt.hidden_import: None,
4142
PyInstOpt.clean: None,
4243
} # TODO: 设法补充类型注解
4344

src/py2exe_gui/Widgets/center_widget.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .add_data_widget import AddDataWindow
2424
from .arguments_browser import ArgumentsBrowser
2525
from .dialog_widgets import IconFileDlg, ScriptFileDlg
26+
from .multi_item_edit_widget import MultiPkgEditWindow
2627
from .pyenv_combobox import PyEnvComboBox
2728
from .pyinstaller_option_widget import load_pyinst_options
2829

@@ -75,6 +76,11 @@ def __init__(self, parent: QMainWindow) -> None:
7576
self.add_binary_dlg = AddDataWindow()
7677
self.binary_item_list: list[AddDataWindow.data_item] = []
7778

79+
# 添加隐式导入
80+
self.hidden_import_btn = QPushButton()
81+
self.hidden_import_dlg = MultiPkgEditWindow()
82+
self.hidden_import_list: list[str] = []
83+
7884
# 清理缓存与临时文件
7985
self.clean_checkbox = QCheckBox()
8086

@@ -113,6 +119,9 @@ def _setup_ui(self) -> None:
113119
self.add_data_dlg.setWindowTitle("添加数据文件")
114120
self.add_binary_dlg.setWindowTitle("添加二进制文件")
115121

122+
self.hidden_import_btn.setText("隐式导入")
123+
self.hidden_import_dlg.setWindowTitle("Hidden import")
124+
116125
self.clean_checkbox.setText("清理")
117126
self.clean_checkbox.setChecked(False)
118127
self.pyinstaller_args_browser.setMaximumHeight(80)
@@ -123,11 +132,15 @@ def _setup_ui(self) -> None:
123132
# 将 PyInstaller 选项详情设置成各控件的 ToolTip
124133
if self.option_dict:
125134
opt = self.option_dict
135+
# TODO: 解绑文本文档中的option字符和此处opt的键
126136
self.project_name_label.setToolTip(opt["-n NAME, --name NAME"])
127137
self.one_dir_btn.setToolTip(opt["-D, --onedir"])
128138
self.one_file_btn.setToolTip(opt["-F, --onefile"])
129139
self.add_data_btn.setToolTip(opt["--add-data SOURCE:DEST"])
130140
self.add_binary_btn.setToolTip(opt["--add-binary SOURCE:DEST"])
141+
self.hidden_import_btn.setToolTip(
142+
opt["--hidden-import MODULENAME, --hiddenimport MODULENAME"]
143+
)
131144
self.clean_checkbox.setToolTip(opt["--clean"])
132145

133146
def _connect_slots(self) -> None:
@@ -205,6 +218,24 @@ def add_binary_selected(binary_item_list: list) -> None:
205218
self.parent_widget.statusBar().showMessage("添加二进制文件已更新")
206219
self.option_selected.emit((PyInstOpt.add_binary, binary_item_list))
207220

221+
@QtCore.Slot()
222+
def handle_hidden_import_btn_clicked() -> None:
223+
"""
224+
点击隐式导入按钮的槽函数 \n
225+
"""
226+
self.hidden_import_dlg.show()
227+
228+
@QtCore.Slot(list)
229+
def hidden_import_selected(hidden_import_list: list[str]) -> None:
230+
"""
231+
用户完成了隐式导入编辑操作的槽函数 \n
232+
:param hidden_import_list: 隐式导入项列表
233+
"""
234+
235+
self.hidden_import_list = hidden_import_list
236+
self.parent_widget.statusBar().showMessage("隐式导入已更新")
237+
self.option_selected.emit((PyInstOpt.hidden_import, hidden_import_list))
238+
208239
@QtCore.Slot(bool)
209240
def clean_selected(selected: bool) -> None:
210241
"""
@@ -229,6 +260,8 @@ def clean_selected(selected: bool) -> None:
229260
self.add_data_dlg.data_selected.connect(add_data_selected)
230261
self.add_binary_btn.clicked.connect(handle_add_binary_btn_clicked)
231262
self.add_binary_dlg.data_selected.connect(add_binary_selected)
263+
self.hidden_import_btn.clicked.connect(handle_hidden_import_btn_clicked)
264+
self.hidden_import_dlg.items_selected.connect(hidden_import_selected)
232265
self.clean_checkbox.toggled.connect(clean_selected)
233266

234267
def _set_layout(self) -> None:
@@ -266,6 +299,8 @@ def _set_layout(self) -> None:
266299
main_layout.addStretch(10)
267300
main_layout.addLayout(add_btn_layout)
268301
main_layout.addStretch(10)
302+
main_layout.addWidget(self.hidden_import_btn)
303+
main_layout.addStretch(10)
269304
main_layout.addWidget(self.clean_checkbox)
270305
main_layout.addStretch(10)
271306
main_layout.addWidget(self.pyinstaller_args_browser)

src/py2exe_gui/Widgets/dialog_widgets.py

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,16 @@
55
from typing import Optional
66

77
from PySide6.QtCore import Qt
8-
from PySide6.QtGui import QPixmap
9-
from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget
8+
from PySide6.QtGui import QIcon, QPixmap
9+
from PySide6.QtWidgets import (
10+
QDialog,
11+
QFileDialog,
12+
QHeaderView,
13+
QMessageBox,
14+
QTableWidget,
15+
QVBoxLayout,
16+
QWidget,
17+
)
1018

1119
from ..Utilities import QtFileOpen
1220

@@ -90,3 +98,58 @@ def about_text(self) -> str:
9098
self._about_text = "无法打开关于文档,请尝试重新获取本程序。"
9199

92100
return self._about_text
101+
102+
103+
class PkgBrowserDlg(QDialog):
104+
"""
105+
浏览已安装的所有包的对话框
106+
"""
107+
108+
def __init__(self, parent: Optional[QWidget] = None) -> None:
109+
"""
110+
:param parent: 父控件对象
111+
"""
112+
113+
super().__init__(parent)
114+
115+
self.pkg_list: list[tuple[str, str]] = [] # [("black", "23.12.1"), ...]
116+
117+
self.pkg_table = QTableWidget(self)
118+
119+
self._setup_ui()
120+
121+
def _setup_ui(self) -> None:
122+
"""
123+
处理 UI \n
124+
"""
125+
126+
self.setWindowTitle("已安装的包")
127+
self.setWindowIcon(QIcon(QPixmap(":/Icons/Python_128px")))
128+
129+
self.pkg_table.setColumnCount(2)
130+
self.pkg_table.setHorizontalHeaderLabels(["包名", "版本"])
131+
self.pkg_table.horizontalHeader().setSectionResizeMode(
132+
0, QHeaderView.ResizeMode.Stretch
133+
)
134+
self.pkg_table.horizontalHeader().setSectionResizeMode(
135+
1, QHeaderView.ResizeMode.Stretch
136+
)
137+
138+
main_layout = QVBoxLayout()
139+
main_layout.setSpacing(0)
140+
main_layout.setContentsMargins(0, 0, 0, 0)
141+
main_layout.addWidget(self.pkg_table)
142+
self.setLayout(main_layout)
143+
144+
def load_pkg_list(self, pkg_list: list[dict[str, str]]) -> None:
145+
"""
146+
从后端加载包数据,存储到实例属性中 \n
147+
:param pkg_list: 已安装的包列表,形如 [{"name": "black", "version": "23.12.1"}, {}, ...]
148+
"""
149+
150+
package_lists = []
151+
for pkg in pkg_list:
152+
pkg_name = pkg["name"]
153+
pkg_version = pkg["version"]
154+
package_lists.append((pkg_name, pkg_version))
155+
self.pkg_list = package_lists

src/py2exe_gui/Widgets/multi_item_edit_widget.py

Lines changed: 3 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
# Licensed under the GPLv3 License: https://www.gnu.org/licenses/gpl-3.0.html
22
# For details: https://github.com/muziing/Py2exe-GUI/blob/main/README.md#license
33

4-
import sys
54
from typing import Optional
65

76
from PySide6.QtCore import Qt, Signal, Slot
87
from PySide6.QtGui import QIcon, QPixmap
98
from PySide6.QtWidgets import (
10-
QApplication,
11-
QDialog,
129
QHBoxLayout,
13-
QHeaderView,
1410
QListWidget,
1511
QListWidgetItem,
1612
QPushButton,
17-
QTableWidget,
1813
QVBoxLayout,
1914
QWidget,
2015
)
2116

17+
from .dialog_widgets import PkgBrowserDlg
18+
2219

2320
class MultiItemEditWindow(QWidget):
2421
"""
@@ -132,7 +129,7 @@ def _submit(self) -> list[str]:
132129
item_list = []
133130

134131
for row in range(self.item_list_widget.count()):
135-
item_text = self.item_list_widget.item(row=row).text()
132+
item_text = self.item_list_widget.item(row).text()
136133
if item_text == "":
137134
self.item_list_widget.takeItem(row)
138135
else:
@@ -161,8 +158,6 @@ class MultiPkgEditWindow(MultiItemEditWindow):
161158
并将包名作为条目添加的功能 \n
162159
"""
163160

164-
# TODO 实现一个能够浏览并选中/多选Python包的对话框窗口
165-
166161
def __init__(self, parent: Optional[QWidget] = None):
167162
"""
168163
:param parent: 父控件对象
@@ -192,65 +187,3 @@ def _connect_slots(self) -> None:
192187
super()._connect_slots()
193188

194189
self.browse_pkg_button.clicked.connect(self.pkg_browser_dlg.exec)
195-
196-
197-
class PkgBrowserDlg(QDialog):
198-
"""
199-
浏览已安装的所有包的对话框
200-
"""
201-
202-
def __init__(self, parent: Optional[QWidget] = None) -> None:
203-
"""
204-
:param parent: 父控件对象
205-
"""
206-
207-
super().__init__(parent)
208-
209-
self.pkg_list: list[tuple[str, str]] = [] # [("black", "23.12.1"), ...]
210-
211-
self.pkg_table = QTableWidget(self)
212-
213-
self._setup_ui()
214-
215-
def _setup_ui(self) -> None:
216-
"""
217-
处理 UI \n
218-
"""
219-
220-
self.setWindowTitle("已安装的包")
221-
self.setWindowIcon(QIcon(QPixmap(":/Icons/Python_128px")))
222-
223-
self.pkg_table.setColumnCount(2)
224-
self.pkg_table.setHorizontalHeaderLabels(["包名", "版本"])
225-
self.pkg_table.horizontalHeader().setSectionResizeMode(
226-
0, QHeaderView.ResizeMode.Stretch
227-
)
228-
self.pkg_table.horizontalHeader().setSectionResizeMode(
229-
1, QHeaderView.ResizeMode.Stretch
230-
)
231-
232-
main_layout = QVBoxLayout()
233-
main_layout.setSpacing(0)
234-
main_layout.setContentsMargins(0, 0, 0, 0)
235-
main_layout.addWidget(self.pkg_table)
236-
self.setLayout(main_layout)
237-
238-
def load_pkg_list(self, pkg_list: list[dict[str, str]]) -> None:
239-
"""
240-
从后端加载包数据,存储到实例属性中 \n
241-
:param pkg_list: 已安装的包列表,形如 [{"name": "black", "version": "23.12.1"}, {}, ...]
242-
"""
243-
244-
package_lists = []
245-
for pkg in pkg_list:
246-
pkg_name = pkg["name"]
247-
pkg_version = pkg["version"]
248-
package_lists.append((pkg_name, pkg_version))
249-
self.pkg_list = package_lists
250-
251-
252-
if __name__ == "__main__":
253-
app = QApplication(sys.argv)
254-
window = MultiPkgEditWindow()
255-
window.show()
256-
sys.exit(app.exec())

0 commit comments

Comments
 (0)