添加下载模板功能

This commit is contained in:
2025-06-29 00:06:47 +08:00
parent 9d703212ef
commit 375ea9a686
16 changed files with 143 additions and 20 deletions

View File

@@ -42,7 +42,7 @@ class DTGWorker(QObject):
max_question_count = math.ceil(len(students) * 3 / len(questions))
d = DocPaper(self.output_filename, template_path=resource_path("template/template-2.docx"))
d = DocPaper(self.output_filename, resource_path("template/template-defense-paper-paper.docx"))
for index, student in enumerate(students):
if (p := int((index + 1) / len(students) * 100)) != 100:
self.progress[int].emit(p)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,8 +1,10 @@
import random
from typing import Union
from PySide6.QtCore import QTimer, Qt, Signal
from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame
from qfluentwidgets import DisplayLabel, LargeTitleLabel
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame, QLayout
from qfluentwidgets import DisplayLabel, LargeTitleLabel, GroupHeaderCardWidget, FluentIconBase, CardGroupWidget
from module.picker.schema import PickerStudent
@@ -68,3 +70,27 @@ class RollingTextWidget(QWidget):
def clear_text(self):
self.soLabel.clear()
self.nameLabel.clear()
class MyCardGroupWidget(CardGroupWidget):
def addLayout(self, layout: QLayout, stretch=0):
self.hBoxLayout.addLayout(layout, stretch=stretch)
class MyGroupHeaderCardWidget(GroupHeaderCardWidget):
def addGroup(self, icon: Union[str, FluentIconBase, QIcon], title: str, content: str,
object: Union[QWidget, QLayout],
stretch=0) -> CardGroupWidget:
group = MyCardGroupWidget(icon, title, content, self)
if isinstance(object, QWidget):
group.addWidget(object, stretch=stretch)
elif isinstance(object, QLayout):
group.addLayout(object, stretch=stretch)
if self.groupWidgets:
self.groupWidgets[-1].setSeparatorVisible(True)
self.groupLayout.addWidget(group)
self.groupWidgets.append(group)
return group

View File

@@ -5,16 +5,17 @@ from typing import Callable, Literal
from PySide6.QtCore import Qt, Signal, QThread
from PySide6.QtWidgets import QVBoxLayout, QFileDialog, QHBoxLayout
from qfluentwidgets import GroupHeaderCardWidget, FluentIcon, PushButton, LineEdit, IconWidget, BodyLabel, \
PrimaryPushButton, SwitchButton
PrimaryPushButton, SwitchButton, HyperlinkButton
from module import LOGLEVEL
from module.worker import ARGWorker
from ui import MAIN_THEME_COLOR
from ui.components.infobar import ProgressInfoBar
from ui.components.widget import Widget
from ui.components.widget import Widget, MyGroupHeaderCardWidget
from utils.function import open_template
class InputSettingCard(GroupHeaderCardWidget):
class InputSettingCard(MyGroupHeaderCardWidget):
chooseSignal = Signal(str)
def __init__(self, parent=None):
@@ -22,15 +23,20 @@ class InputSettingCard(GroupHeaderCardWidget):
self.setTitle("输入选项")
self.setBorderRadius(8)
self.btnHBoxLayout = QHBoxLayout(self)
self.openTemplateButton = HyperlinkButton("", "下载模板")
self.chooseFileButton = PushButton("打开")
self.chooseFileButton.setFixedWidth(120)
self.btnHBoxLayout.addWidget(self.openTemplateButton)
self.btnHBoxLayout.addWidget(self.chooseFileButton)
self.inputGroup = self.addGroup(FluentIcon.DOCUMENT, "目标文件", "选择达成度计算表", self.chooseFileButton)
self.inputGroup = self.addGroup(FluentIcon.DOCUMENT, "目标文件", "选择达成度计算表", self.btnHBoxLayout)
# ============================
self.chooseFileButton.clicked.connect(self.choose_file)
self.openTemplateButton.clicked.connect(lambda: open_template('template-achievement-file.xlsm', self))
def choose_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Excel 文件 (*.xlsm);")

View File

@@ -1,18 +1,43 @@
from functools import wraps
from typing import Literal, Callable
from PySide6.QtCore import Qt, Signal, QThread
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QFileDialog, QButtonGroup, QWidget
from PySide6.QtCore import Qt, Signal, QThread, QEvent
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QFileDialog, QButtonGroup, QWidget, QApplication
from qfluentwidgets import GroupHeaderCardWidget, PushButton, IconWidget, BodyLabel, PrimaryPushButton, FluentIcon, \
LineEdit, RadioButton
LineEdit, RadioButton, HyperlinkButton, FlyoutViewBase, TeachingTipView, TeachingTip, TeachingTipTailPosition
from module.worker import DTGWorker
from ui import MAIN_THEME_COLOR
from ui.components.infobar import ProgressInfoBar
from ui.components.widget import Widget
from ui.components.widget import Widget, MyGroupHeaderCardWidget
from utils.function import open_template
class InitSettingCard(GroupHeaderCardWidget):
class ChooseTemplateView(FlyoutViewBase):
closed = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.vBoxLayout = QVBoxLayout(self)
QApplication.instance().installEventFilter(self)
def paintEvent(self, e):
...
def eventFilter(self, watched, event):
if event.type() == QEvent.MouseButtonPress:
if not self.rect().contains(self.mapFromGlobal(event.globalPosition().toPoint())):
self.closed.emit()
return super().eventFilter(watched, event)
def addTemplate(self, content: str, cb: Callable[[], None]):
label = HyperlinkButton("", content)
self.vBoxLayout.addWidget(label)
label.clicked.connect(cb)
label.clicked.connect(self.closed.emit)
class InitSettingCard(MyGroupHeaderCardWidget):
chooseSignal = Signal(str, str)
def __init__(self, parent=None):
@@ -21,19 +46,29 @@ class InitSettingCard(GroupHeaderCardWidget):
self.setTitle("输入选项")
self.setBorderRadius(8)
self.sBtnHBoxLayout = QHBoxLayout(self)
self.qBtnHBoxLayout = QHBoxLayout(self)
self.sTemplateButton = HyperlinkButton("", "下载模板")
self.chooseStudentButton = PushButton("打开")
self.qTemplateButton = HyperlinkButton("", "下载模板")
self.chooseQuestionButton = PushButton("打开")
self.chooseStudentButton.setFixedWidth(120)
self.chooseQuestionButton.setFixedWidth(120)
self.sBtnHBoxLayout.addWidget(self.sTemplateButton)
self.sBtnHBoxLayout.addWidget(self.chooseStudentButton)
self.qBtnHBoxLayout.addWidget(self.qTemplateButton)
self.qBtnHBoxLayout.addWidget(self.chooseQuestionButton)
self.stuGroup = self.addGroup(FluentIcon.DOCUMENT, "学生名单", "选择学生名单文件", self.chooseStudentButton)
self.QueGroup = self.addGroup(FluentIcon.DOCUMENT, "题库", "选择题库文件", self.chooseQuestionButton)
self.stuGroup = self.addGroup(FluentIcon.DOCUMENT, "学生名单", "选择学生名单文件", self.sBtnHBoxLayout)
self.QueGroup = self.addGroup(FluentIcon.DOCUMENT, "题库", "选择题库文件", self.qBtnHBoxLayout)
self.chooseStudentButton.clicked.connect(
lambda: self.choose_file(self.stuGroup.setContent, "已选择文件:", lambda x: self.chooseSignal.emit('s', x)))
self.chooseQuestionButton.clicked.connect(
lambda: self.choose_file(self.QueGroup.setContent, "已选择文件:", lambda x: self.chooseSignal.emit('q', x)))
self.qTemplateButton.clicked.connect(lambda: open_template('template-defense-paper-questions.xlsm', self))
self.sTemplateButton.clicked.connect(self.show_template_list_view)
def choose_file(
self,
@@ -47,6 +82,19 @@ class InitSettingCard(GroupHeaderCardWidget):
if cb:
cb(file_path)
def show_template_list_view(self):
view = ChooseTemplateView(self)
view.addTemplate("普通模板", lambda: open_template("template-defense-paper-student-1.xlsm", self))
view.addTemplate("达成度模板", lambda: open_template("template-defense-paper-student-2.xlsm", self))
w = TeachingTip.make(
target=self.sTemplateButton,
view=view,
tailPosition=TeachingTipTailPosition.TOP,
duration=-1,
parent=self
)
view.closed.connect(w.close)
class ExportSettingsCard(GroupHeaderCardWidget):
startSignal = Signal()

View File

@@ -1,12 +1,13 @@
from PySide6.QtCore import Qt, Signal, QTimer
from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget, QFileDialog
from qfluentwidgets import GroupHeaderCardWidget, PushButton, FluentIcon, PrimaryPushButton, IconWidget, BodyLabel, \
SpinBox
from qfluentwidgets import PushButton, FluentIcon, PrimaryPushButton, IconWidget, BodyLabel, \
SpinBox, HyperlinkButton
from module.picker.schema import PickerExcel, PickerStudent
from ui import MAIN_THEME_COLOR
from ui.components.widget import Widget
from ui.components.widget import Widget, MyGroupHeaderCardWidget
from ui.pyui.sub.picker import PickStudentLabelUi
from utils.function import open_template
class PickStudentMode(QWidget):
@@ -15,10 +16,12 @@ class PickStudentMode(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.card = GroupHeaderCardWidget(self)
self.card = MyGroupHeaderCardWidget(self)
self.vbox = QVBoxLayout(self)
self.vbox.setContentsMargins(0, 0, 0, 0)
self.btnHBox = QHBoxLayout(self)
self.openTemplateBtn = HyperlinkButton("", "下载模板")
self.chooseBtn = PushButton("打开")
self.startButton = PrimaryPushButton(FluentIcon.PLAY_SOLID, "开始")
self.bottomLayout = QHBoxLayout()
@@ -45,8 +48,10 @@ class PickStudentMode(QWidget):
self.bottomLayout.addStretch(1)
self.bottomLayout.addWidget(self.startButton, 0, Qt.AlignRight)
self.bottomLayout.setAlignment(Qt.AlignVCenter)
self.btnHBox.addWidget(self.openTemplateBtn)
self.btnHBox.addWidget(self.chooseBtn)
self.group = self.card.addGroup(FluentIcon.DOCUMENT, "学生名单", "选择学生名单", self.chooseBtn)
self.group = self.card.addGroup(FluentIcon.DOCUMENT, "学生名单", "选择学生名单", self.btnHBox)
self.spinGroup = self.card.addGroup(FluentIcon.SETTING, "提问次数", "设置提问的最大次数", self.spinbox)
self.spinGroup.setSeparatorVisible(True)
self.card.vBoxLayout.addLayout(self.bottomLayout)
@@ -60,6 +65,7 @@ class PickStudentMode(QWidget):
self.spinbox.valueChanged.connect(lambda: PickerExcel.save_total_time(value=self.spinbox.value()))
self.startButton.clicked.connect(self.start_rolling)
self.psui.rollingText.finishSignal.connect(self.finish_rolling)
self.openTemplateBtn.clicked.connect(lambda: open_template("template-pick-student.xlsm", self))
# ==============================
self.filepath = ""
self.students = []

View File

@@ -3,7 +3,7 @@ import sys
from PySide6.QtCore import Signal
from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QApplication, QGridLayout
from qfluentwidgets import PushButton, SpinBox, PrimaryPushButton, \
BodyLabel
BodyLabel, CommandBarView, Action, FluentIcon, Flyout, FlyoutAnimationType
from ui.components.widget import RollingTextWidget

View File

@@ -1,10 +1,16 @@
import io
import os
import re
import shutil
import sys
import tempfile
from typing import Optional
import matplotlib
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QWidget
from matplotlib import pyplot as plt
from qfluentwidgets import InfoBar, InfoBarPosition
def format_ranges(nums):
@@ -185,4 +191,35 @@ def resource_path(relative_path: str) -> str:
return os.path.join(base_path, relative_path)
def open_template(file_name: str, widget: QWidget) -> None:
"""将模板文件复制到临时目录并打开"""
file_path = resource_path("template/" + file_name)
if not os.path.exists(file_path):
raise FileNotFoundError(f"Template file '{file_name}' not found.")
# 复制到临时目录
tmp_dir = tempfile.gettempdir()
tmp_file_path = os.path.join(tmp_dir, file_name)
shutil.copy(file_path, tmp_file_path)
# 打开文件
if sys.platform.startswith('win'):
os.startfile(tmp_file_path)
elif sys.platform.startswith('darwin'):
os.system(f'open "{tmp_file_path}"')
else:
os.system(f'xdg-open "{tmp_file_path}"')
InfoBar.info(
title='已打开文件',
content="编辑后请将文件另存为,保存至其他目录",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP_RIGHT,
duration=2000,
parent=widget
)
DEVELOPMENT_ENV = getattr(sys, 'frozen', False)