Add --add-data and --add-binary

为主界面和打包流程「添加数据文件」与「添加二进制文件」功能;
This commit is contained in:
muzing 2023-12-20 10:58:20 +08:00
parent 85497bf47e
commit 50d8d5e796
5 changed files with 81 additions and 12 deletions

View File

@ -15,4 +15,6 @@ class PyinstallerArgs(enum.IntFlag):
FD = enum.auto() FD = enum.auto()
console = enum.auto() console = enum.auto()
out_name = enum.auto() out_name = enum.auto()
add_data = enum.auto()
add_binary = enum.auto()
clean = enum.auto() clean = enum.auto()

View File

@ -69,6 +69,12 @@ class Packaging(QtCore.QObject):
self._args.extend(["--name", self.args_dict[PyinstallerArgs.out_name]]) self._args.extend(["--name", self.args_dict[PyinstallerArgs.out_name]])
if self.args_dict[PyinstallerArgs.clean]: if self.args_dict[PyinstallerArgs.clean]:
self._args.append(self.args_dict[PyinstallerArgs.clean]) self._args.append(self.args_dict[PyinstallerArgs.clean])
if self.args_dict[PyinstallerArgs.add_data]:
for item in self.args_dict[PyinstallerArgs.add_data]:
self._args.append(f"--add-data {item[0]}:{item[1]}")
if self.args_dict[PyinstallerArgs.add_binary]:
for item in self.args_dict[PyinstallerArgs.add_binary]:
self._args.append(f"--add-binary {item[0]}:{item[1]}")
self.args_settled.emit(self._args) self.args_settled.emit(self._args)

View File

@ -1,6 +1,7 @@
# Licensed under the GPLv3 License: https://www.gnu.org/licenses/gpl-3.0.html # Licensed under the GPLv3 License: https://www.gnu.org/licenses/gpl-3.0.html
# For details: https://github.com/muziing/Py2exe-GUI/blob/main/README.md#license # For details: https://github.com/muziing/Py2exe-GUI/blob/main/README.md#license
from .add_data_widget import AddDataWindow
from .arguments_browser import ArgumentsBrowser from .arguments_browser import ArgumentsBrowser
from .center_widget import CenterWidget from .center_widget import CenterWidget
from .dialog_widgets import * from .dialog_widgets import *

View File

@ -34,8 +34,7 @@ class AddDataWindow(QWidget):
super().__init__(parent) super().__init__(parent)
# 工作目录,应由主界面提供,默认为入口脚本所在目录;各种文件处理将以此作为相对路径起点 # 工作目录,应由主界面提供,默认为入口脚本所在目录;各种文件处理将以此作为相对路径起点
self.work_dir: Path = Path(".").resolve() self._work_dir: Path = Path(".").resolve()
# self.work_dir = Path("D:/Works/Py2exe-GUI/src/py2exe_gui/") # 测试用
# 浏览系统文件/目录的文件对话框 # 浏览系统文件/目录的文件对话框
self.data_browse_dlg = QFileDialog(self) self.data_browse_dlg = QFileDialog(self)
@ -64,13 +63,11 @@ class AddDataWindow(QWidget):
处理 UI 内容 \n 处理 UI 内容 \n
""" """
self.setWindowTitle("添加数据") self.setWindowTitle("添加文件")
self.setMinimumWidth(550) self.setMinimumWidth(550)
self.data_browse_dlg.setFileMode(QFileDialog.FileMode.ExistingFile) self.data_browse_dlg.setFileMode(QFileDialog.FileMode.ExistingFile)
self.data_browse_dlg.setDirectory(str(self.work_dir))
self.data_dir_browse_dlg.setFileMode(QFileDialog.FileMode.Directory) self.data_dir_browse_dlg.setFileMode(QFileDialog.FileMode.Directory)
self.data_dir_browse_dlg.setDirectory(str(self.work_dir))
self.item_table.setColumnCount(2) self.item_table.setColumnCount(2)
self.item_table.setRowCount(0) self.item_table.setRowCount(0)
@ -117,6 +114,11 @@ class AddDataWindow(QWidget):
self.setLayout(main_layout) self.setLayout(main_layout)
def set_work_dir(self, work_dir_path: Path) -> None:
self._work_dir = work_dir_path
self.data_browse_dlg.setDirectory(str(work_dir_path))
self.data_dir_browse_dlg.setDirectory(str(work_dir_path))
def _submit(self) -> list[data_item]: def _submit(self) -> list[data_item]:
""" """
将当前界面上的所有配置项转换为 data_item 列表准备提交给主界面和打包流使用 \n 将当前界面上的所有配置项转换为 data_item 列表准备提交给主界面和打包流使用 \n
@ -211,7 +213,7 @@ class AddDataWindow(QWidget):
self.item_table.setItem(current_row, 0, source_item) self.item_table.setItem(current_row, 0, source_item)
# DEST 列设置为表示顶层目录的"."或与入口脚本的相对路径 # DEST 列设置为表示顶层目录的"."或与入口脚本的相对路径
dest_item = QTableWidgetItem(str(path.relative_to(self.work_dir))) dest_item = QTableWidgetItem(str(path.relative_to(self._work_dir)))
# FIXME 处理相对路径错误 # FIXME 处理相对路径错误
if path.is_dir(): if path.is_dir():
self.item_table.setItem(current_row, 1, dest_item) self.item_table.setItem(current_row, 1, dest_item)
@ -224,6 +226,7 @@ class AddDataWindow(QWidget):
self.data_selected.emit(self._submit()) self.data_selected.emit(self._submit())
self.close() self.close()
# noinspection DuplicatedCode
self.new_btn.clicked.connect(new_btn_handle) self.new_btn.clicked.connect(new_btn_handle)
self.delete_btn.clicked.connect(delete_btn_handle) self.delete_btn.clicked.connect(delete_btn_handle)
self.browse_btn.clicked.connect(browse_btn_handle) self.browse_btn.clicked.connect(browse_btn_handle)

View File

@ -8,6 +8,7 @@ from PySide6.QtWidgets import (
QButtonGroup, QButtonGroup,
QCheckBox, QCheckBox,
QGridLayout, QGridLayout,
QHBoxLayout,
QLabel, QLabel,
QLineEdit, QLineEdit,
QMainWindow, QMainWindow,
@ -19,6 +20,7 @@ from PySide6.QtWidgets import (
) )
from ..Constants import PyinstallerArgs from ..Constants import PyinstallerArgs
from .add_data_widget import AddDataWindow
from .arguments_browser import ArgumentsBrowser from .arguments_browser import ArgumentsBrowser
from .dialog_widgets import IconFileDlg, ScriptFileDlg from .dialog_widgets import IconFileDlg, ScriptFileDlg
from .pyenv_combobox import PyEnvComboBox from .pyenv_combobox import PyEnvComboBox
@ -60,6 +62,14 @@ class CenterWidget(QWidget):
self.one_file_btn = QRadioButton() self.one_file_btn = QRadioButton()
self.fd_group = QButtonGroup() self.fd_group = QButtonGroup()
# 添加数据与二进制文件
self.add_data_btn = QPushButton()
self.add_data_dlg = AddDataWindow()
self.data_item_list: list[AddDataWindow.data_item] = []
self.add_binary_btn = QPushButton()
self.add_binary_dlg = AddDataWindow()
self.binary_item_list: list[AddDataWindow.data_item] = []
# 清理缓存与临时文件 # 清理缓存与临时文件
self.clean_checkbox = QCheckBox() self.clean_checkbox = QCheckBox()
@ -93,6 +103,11 @@ class CenterWidget(QWidget):
self.fd_group.addButton(self.one_dir_btn, 0) self.fd_group.addButton(self.one_dir_btn, 0)
self.fd_group.addButton(self.one_file_btn, 1) self.fd_group.addButton(self.one_file_btn, 1)
self.add_data_btn.setText("添加数据文件")
self.add_binary_btn.setText("添加二进制文件")
self.add_data_dlg.setWindowTitle("添加数据文件")
self.add_binary_dlg.setWindowTitle("添加二进制文件")
self.clean_checkbox.setText("清理") self.clean_checkbox.setText("清理")
self.clean_checkbox.setChecked(False) self.clean_checkbox.setChecked(False)
self.pyinstaller_args_browser.setMaximumHeight(80) self.pyinstaller_args_browser.setMaximumHeight(80)
@ -137,6 +152,42 @@ class CenterWidget(QWidget):
self.option_selected.emit((PyinstallerArgs.FD, "--onefile")) self.option_selected.emit((PyinstallerArgs.FD, "--onefile"))
self.parent_widget.statusBar().showMessage("将打包至单个文件中") self.parent_widget.statusBar().showMessage("将打包至单个文件中")
@QtCore.Slot()
def handle_add_data_btn_clicked() -> None:
"""
用户在界面点击添加数据按钮的槽函数 \n
"""
self.add_data_dlg.load_data_item_list(self.data_item_list)
self.add_data_dlg.show()
@QtCore.Slot(list)
def add_data_selected(data_item_list: list) -> None:
"""
用户完成了添加数据操作的槽函数 \n
"""
self.data_item_list = data_item_list
self.option_selected.emit((PyinstallerArgs.add_data, data_item_list))
@QtCore.Slot()
def handle_add_binary_btn_clicked() -> None:
"""
用户在界面点击添加二进制文件按钮的槽函数 \n
"""
self.add_binary_dlg.load_data_item_list(self.binary_item_list)
self.add_binary_dlg.show()
@QtCore.Slot(list)
def add_binary_selected(binary_item_list: list) -> None:
"""
用户完成了添加二进制文件操作的槽函数 \n
"""
self.binary_item_list = binary_item_list
self.option_selected.emit((PyinstallerArgs.add_binary, binary_item_list))
@QtCore.Slot(bool) @QtCore.Slot(bool)
def clean_selected(selected: bool) -> None: def clean_selected(selected: bool) -> None:
""" """
@ -155,8 +206,12 @@ class CenterWidget(QWidget):
self.script_browse_btn.clicked.connect(self.script_file_dlg.open) self.script_browse_btn.clicked.connect(self.script_file_dlg.open)
self.script_file_dlg.fileSelected.connect(script_file_selected) self.script_file_dlg.fileSelected.connect(script_file_selected)
self.project_name_le.editingFinished.connect(project_name_selected) self.project_name_le.editingFinished.connect(project_name_selected)
# noinspection DuplicatedCode
self.fd_group.idClicked.connect(one_fd_selected) self.fd_group.idClicked.connect(one_fd_selected)
self.add_data_btn.clicked.connect(handle_add_data_btn_clicked)
self.add_data_dlg.data_selected.connect(add_data_selected)
self.add_binary_btn.clicked.connect(handle_add_binary_btn_clicked)
self.add_binary_dlg.data_selected.connect(add_binary_selected)
self.clean_checkbox.toggled.connect(clean_selected) self.clean_checkbox.toggled.connect(clean_selected)
def _set_layout(self) -> None: def _set_layout(self) -> None:
@ -178,6 +233,10 @@ class CenterWidget(QWidget):
fd_layout.addWidget(self.one_dir_btn, 1, 0) fd_layout.addWidget(self.one_dir_btn, 1, 0)
fd_layout.addWidget(self.one_file_btn, 1, 1) fd_layout.addWidget(self.one_file_btn, 1, 1)
add_btn_layout = QHBoxLayout()
add_btn_layout.addWidget(self.add_data_btn)
add_btn_layout.addWidget(self.add_binary_btn)
main_layout = QVBoxLayout() main_layout = QVBoxLayout()
self.main_layout = main_layout self.main_layout = main_layout
main_layout.addSpacing(10) main_layout.addSpacing(10)
@ -188,7 +247,7 @@ class CenterWidget(QWidget):
main_layout.addStretch(10) main_layout.addStretch(10)
main_layout.addLayout(fd_layout) main_layout.addLayout(fd_layout)
main_layout.addStretch(10) main_layout.addStretch(10)
main_layout.addLayout(add_btn_layout)
main_layout.addStretch(10) main_layout.addStretch(10)
main_layout.addWidget(self.clean_checkbox) main_layout.addWidget(self.clean_checkbox)
main_layout.addStretch(10) main_layout.addStretch(10)
@ -212,6 +271,8 @@ class CenterWidget(QWidget):
self.parent_widget.statusBar().showMessage( self.parent_widget.statusBar().showMessage(
f"打开脚本路径:{str(script_path.resolve())}" f"打开脚本路径:{str(script_path.resolve())}"
) )
self.add_data_dlg.set_work_dir(script_path.parent)
self.add_binary_dlg.set_work_dir(script_path.parent)
elif option_key == PyinstallerArgs.out_name: elif option_key == PyinstallerArgs.out_name:
self.project_name_le.setText(option_value) self.project_name_le.setText(option_value)
@ -349,10 +410,6 @@ class WinMacCenterWidget(CenterWidget):
if option_key == PyinstallerArgs.script_path: if option_key == PyinstallerArgs.script_path:
script_path = Path(option_value) script_path = Path(option_value)
self.icon_file_dlg.setDirectory(str(script_path.parent.resolve())) self.icon_file_dlg.setDirectory(str(script_path.parent.resolve()))
self.script_path_le.setText(script_path.name)
self.parent_widget.statusBar().showMessage(
f"打开脚本路径:{str(script_path.resolve())}"
)
elif option_key == PyinstallerArgs.icon_path: elif option_key == PyinstallerArgs.icon_path:
icon_path = Path(option_value) icon_path = Path(option_value)