合并达成度功能
This commit is contained in:
243
ui/pyui/achievement_ui.py
Normal file
243
ui/pyui/achievement_ui.py
Normal file
@@ -0,0 +1,243 @@
|
||||
import os
|
||||
from functools import wraps
|
||||
from typing import Callable, Literal
|
||||
|
||||
from PySide6.QtCore import Qt, Signal, QThread
|
||||
from PySide6.QtWidgets import QVBoxLayout, QFileDialog, QHBoxLayout, QProgressBar
|
||||
from qfluentwidgets import GroupHeaderCardWidget, FluentIcon, PushButton, LineEdit, IconWidget, InfoBarIcon, BodyLabel, \
|
||||
PrimaryPushButton, SwitchButton, MessageBox, InfoBar, InfoBarPosition, IndeterminateProgressBar
|
||||
|
||||
from module.worker import ARGWorker
|
||||
from ui.components.widget import Widget
|
||||
|
||||
|
||||
class InputSettingCard(GroupHeaderCardWidget):
|
||||
chooseSignal = Signal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("输入选项")
|
||||
self.setBorderRadius(8)
|
||||
|
||||
self.chooseFileButton = PushButton("打开")
|
||||
|
||||
self.chooseFileButton.setFixedWidth(120)
|
||||
|
||||
self.inputGroup = self.addGroup(FluentIcon.DOCUMENT, "目标文件", "选择达成度计算表", self.chooseFileButton)
|
||||
|
||||
# ============================
|
||||
self.chooseFileButton.clicked.connect(self.choose_file)
|
||||
|
||||
def choose_file(self):
|
||||
file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Excel 文件 (*.xlsm);")
|
||||
if file_path:
|
||||
self.inputGroup.setContent("已选择文件:" + file_path)
|
||||
self.chooseSignal.emit(file_path)
|
||||
|
||||
|
||||
class OutputSettingCard(GroupHeaderCardWidget):
|
||||
updateSignal = Signal(str, str)
|
||||
startSignal = Signal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("输出选项")
|
||||
self.setBorderRadius(8)
|
||||
|
||||
self.chooseExportDirectoryButton = PushButton("选择")
|
||||
self.exportFileNameLineEdit = LineEdit()
|
||||
self.startButton = PrimaryPushButton(FluentIcon.PLAY_SOLID, "开始")
|
||||
self.autoOpenSwitch = SwitchButton()
|
||||
self.disableCompatibilityCheckSwitch = SwitchButton()
|
||||
|
||||
self.autoOpenSwitch.setChecked(True)
|
||||
self.bottomLayout = QHBoxLayout()
|
||||
self.hintIcon = IconWidget(InfoBarIcon.INFORMATION)
|
||||
self.hintLabel = BodyLabel("点击开始按钮以开始生成 👉")
|
||||
self.startButton.setEnabled(False)
|
||||
|
||||
# 设置底部工具栏布局
|
||||
self.hintIcon.setFixedSize(16, 16)
|
||||
self.bottomLayout.setSpacing(10)
|
||||
self.bottomLayout.setContentsMargins(24, 15, 24, 20)
|
||||
self.bottomLayout.addWidget(self.hintIcon, 0, Qt.AlignLeft)
|
||||
self.bottomLayout.addWidget(self.hintLabel, 0, Qt.AlignLeft)
|
||||
self.bottomLayout.addStretch(1)
|
||||
self.bottomLayout.addWidget(self.startButton, 0, Qt.AlignRight)
|
||||
self.bottomLayout.setAlignment(Qt.AlignVCenter)
|
||||
|
||||
self.chooseExportDirectoryButton.setFixedWidth(120)
|
||||
self.exportFileNameLineEdit.setPlaceholderText("请输入文件名")
|
||||
self.startButton.setFixedWidth(120)
|
||||
self.exportFileNameLineEdit.setFixedWidth(360)
|
||||
self.exportFileNameLineEdit.setPlaceholderText("输入导出文件名,例如:21工程管理(1)达成度报告")
|
||||
|
||||
self.dirGroup = self.addGroup(FluentIcon.FOLDER, "导出目录", "选择导出文件的目录",
|
||||
self.chooseExportDirectoryButton)
|
||||
self.fnGroup = self.addGroup(FluentIcon.DOCUMENT, "导出文件名", "输入导出文件名", self.exportFileNameLineEdit)
|
||||
self.aoGroup = self.addGroup(FluentIcon.VIEW, "自动打开", "生成完成后自动打开文件", self.autoOpenSwitch)
|
||||
self.ccGroup = self.addGroup(FluentIcon.DEVELOPER_TOOLS, "关闭兼容性检查",
|
||||
"⚠ 注意:该功能为实验性内容,仅当你明确了解其影响并知道自己在做什么时,才建议关闭兼容性检查!",
|
||||
self.disableCompatibilityCheckSwitch)
|
||||
self.ccGroup.setSeparatorVisible(True)
|
||||
self.vBoxLayout.addLayout(self.bottomLayout)
|
||||
|
||||
# =============================
|
||||
self.chooseExportDirectoryButton.clicked.connect(self.choose_dir)
|
||||
self.startButton.clicked.connect(self.startSignal)
|
||||
|
||||
def choose_dir(self) -> None:
|
||||
dir_path = QFileDialog.getExistingDirectory(self, "选择文件夹", "")
|
||||
if dir_path:
|
||||
self.dirGroup.setContent(f"当前保存的文件目录:{dir_path}")
|
||||
self.updateSignal.emit('d', dir_path)
|
||||
|
||||
def update_path_and_filename_by_input_path(self, path: str):
|
||||
dir_path = path[:path.rfind("/")]
|
||||
self.dirGroup.setContent(f"已选择目录:{dir_path}")
|
||||
self.updateSignal.emit('d', dir_path)
|
||||
|
||||
file_name = path[path.rfind("/") + 1:path.rfind(".")] + "-达成度报告"
|
||||
self.exportFileNameLineEdit.setText(file_name)
|
||||
self.updateSignal.emit('f', file_name)
|
||||
|
||||
|
||||
class AchievementWidget(Widget):
|
||||
error = Signal(str, str)
|
||||
|
||||
def __init__(self, key: str, parent=None):
|
||||
super().__init__(key, parent)
|
||||
|
||||
self.inputGroup = InputSettingCard(self)
|
||||
self.outputGroup = OutputSettingCard(self)
|
||||
self.vbox = QVBoxLayout(self)
|
||||
|
||||
self.vbox.addWidget(self.inputGroup)
|
||||
self.vbox.addWidget(self.outputGroup)
|
||||
self.vbox.addStretch(1)
|
||||
|
||||
# =================================
|
||||
|
||||
self.infoBar = None
|
||||
|
||||
# =================================
|
||||
|
||||
self.thread = None
|
||||
self.worker = None
|
||||
|
||||
# ==================================
|
||||
|
||||
self.input_file_path = ""
|
||||
self.output_file_path = ""
|
||||
self.output_file_name = ""
|
||||
|
||||
# ==================================
|
||||
|
||||
self.inputGroup.chooseSignal.connect(self.input_signal_receive)
|
||||
self.outputGroup.updateSignal.connect(self.export_signal_receive)
|
||||
self.outputGroup.startSignal.connect(self.start_generate)
|
||||
|
||||
def enable_start_check(func: Callable):
|
||||
@wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
result = func(self, *args, **kwargs)
|
||||
|
||||
fields = [
|
||||
self.input_file_path,
|
||||
self.output_file_path,
|
||||
self.output_file_name,
|
||||
]
|
||||
if all(fields):
|
||||
self.outputGroup.startButton.setEnabled(True)
|
||||
else:
|
||||
self.outputGroup.startButton.setEnabled(False)
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
@enable_start_check
|
||||
def set_value(
|
||||
self,
|
||||
key: Literal['input_file_path', 'output_file_path', 'output_file_name'],
|
||||
value: str
|
||||
) -> None:
|
||||
setattr(self, key, value)
|
||||
|
||||
def input_signal_receive(self, file_path: str) -> None:
|
||||
self.set_value('input_file_path', file_path)
|
||||
self.outputGroup.update_path_and_filename_by_input_path(file_path)
|
||||
|
||||
def export_signal_receive(self, s_type: Literal['d', 'f'], value: str) -> None:
|
||||
if s_type == 'd':
|
||||
self.set_value('output_file_path', value)
|
||||
elif s_type == 'f':
|
||||
self.set_value('output_file_name', value)
|
||||
|
||||
def start_generate(self):
|
||||
self.thread = QThread()
|
||||
self.worker = ARGWorker(
|
||||
self.input_file_path,
|
||||
self.output_file_path,
|
||||
self.output_file_name,
|
||||
disable_cc=self.outputGroup.disableCompatibilityCheckSwitch.isChecked()
|
||||
)
|
||||
self.worker.moveToThread(self.thread)
|
||||
|
||||
self.outputGroup.startButton.setEnabled(False)
|
||||
|
||||
# 线程启动与信号连接
|
||||
self.thread.started.connect(self.worker.run)
|
||||
|
||||
self.show_info_bar('')
|
||||
self.worker.error.connect(self.show_error)
|
||||
|
||||
self.worker.finished.connect(self.thread.quit)
|
||||
self.worker.finished.connect(self.worker.deleteLater)
|
||||
self.thread.finished.connect(self.thread.deleteLater)
|
||||
self.thread.finished.connect(self.clear_thread_worker_refs)
|
||||
self.thread.finished.connect(self.after_generate)
|
||||
|
||||
# 启动线程
|
||||
self.thread.start()
|
||||
|
||||
def clear_thread_worker_refs(self):
|
||||
self.thread = None
|
||||
self.worker = None
|
||||
|
||||
def after_generate(self):
|
||||
self.outputGroup.startButton.setEnabled(True)
|
||||
if self.outputGroup.autoOpenSwitch.isChecked():
|
||||
try:
|
||||
os.startfile(self.output_file_path + "/" + self.output_file_name + ".docx")
|
||||
except Exception as e:
|
||||
self.show_error("?? 不好出错了", str(e))
|
||||
if self.infoBar:
|
||||
self.infoBar.close()
|
||||
self.infoBar = InfoBar.success(
|
||||
title='成功!',
|
||||
content="正在打开文件" if self.outputGroup.autoOpenSwitch.isChecked() else "文件已保存",
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.BOTTOM,
|
||||
duration=5000,
|
||||
parent=self
|
||||
)
|
||||
|
||||
def show_error(self, title: str, content: str):
|
||||
self.error.emit(title, content)
|
||||
|
||||
def show_info_bar(self, info: str):
|
||||
self.infoBar = InfoBar(
|
||||
icon=InfoBarIcon.INFORMATION,
|
||||
title='请稍后',
|
||||
content=info,
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=False,
|
||||
position=InfoBarPosition.BOTTOM,
|
||||
duration=-1,
|
||||
parent=self
|
||||
)
|
||||
self.infoBar.addWidget(IndeterminateProgressBar(start=True))
|
||||
self.infoBar.show()
|
||||
Reference in New Issue
Block a user