修改界面
This commit is contained in:
49
ui/pyui/about_ui.py
Normal file
49
ui/pyui/about_ui.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from PySide6.QtGui import QDesktopServices
|
||||
from PySide6.QtWidgets import QVBoxLayout
|
||||
from qfluentwidgets import PrimaryPushSettingCard, FluentIcon, GroupHeaderCardWidget, PushButton
|
||||
|
||||
from ui.components.widget import Widget
|
||||
|
||||
|
||||
class AboutWidget(Widget):
|
||||
def __init__(self, key: str, parent=None):
|
||||
super().__init__(key, parent)
|
||||
|
||||
self.version_card = PrimaryPushSettingCard(
|
||||
text="获取源码",
|
||||
icon=FluentIcon.INFO,
|
||||
title="关于",
|
||||
content="作者:许方杰。当前版本:1.0.0\n使用 GPLv3 开源协议,作者不对使用本软件造成的任何损失负责。"
|
||||
)
|
||||
self.button_list = [
|
||||
PushButton("访问网站"),
|
||||
PushButton("访问网站"),
|
||||
PushButton("访问网站"),
|
||||
PushButton("访问网站"),
|
||||
]
|
||||
self.url_list = [
|
||||
"https://qt.io",
|
||||
"https://qfluentwidgets.com",
|
||||
"https://openpyxl.readthedocs.io/en/stable",
|
||||
"https://github.com/python-openxml/python-docx"
|
||||
]
|
||||
self.group_card = GroupHeaderCardWidget(self)
|
||||
self.group_card.setTitle("第三方框架")
|
||||
self.vbox = QVBoxLayout(self)
|
||||
|
||||
self.vbox.addWidget(self.version_card)
|
||||
self.vbox.addWidget(self.group_card)
|
||||
self.vbox.addStretch(1)
|
||||
|
||||
self.group_card.addGroup("", "PySide6", self.url_list[0], self.button_list[0])
|
||||
self.group_card.addGroup("", "QFluentWidgets", self.url_list[1], self.button_list[1])
|
||||
self.group_card.addGroup("", "openpyxl", self.url_list[2], self.button_list[2])
|
||||
self.group_card.addGroup("", "python-docx", self.url_list[3], self.button_list[3])
|
||||
|
||||
self.version_card.clicked.connect(
|
||||
lambda: QDesktopServices.openUrl("https://cantyonion.site/git/cantyonion/DefenseTopicGenerator")
|
||||
)
|
||||
self.button_list[0].clicked.connect(lambda: QDesktopServices.openUrl(self.url_list[0]))
|
||||
self.button_list[1].clicked.connect(lambda: QDesktopServices.openUrl(self.url_list[1]))
|
||||
self.button_list[2].clicked.connect(lambda: QDesktopServices.openUrl(self.url_list[2]))
|
||||
self.button_list[3].clicked.connect(lambda: QDesktopServices.openUrl(self.url_list[3]))
|
||||
243
ui/pyui/defense_ui.py
Normal file
243
ui/pyui/defense_ui.py
Normal file
@@ -0,0 +1,243 @@
|
||||
from typing import Literal, Callable
|
||||
from functools import wraps
|
||||
|
||||
from PySide6.QtCore import Qt, Signal, QThread
|
||||
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QFileDialog
|
||||
from qfluentwidgets import GroupHeaderCardWidget, PushButton, IconWidget, InfoBarIcon, \
|
||||
BodyLabel, PrimaryPushButton, FluentIcon, LineEdit, InfoBar, InfoBarPosition, ProgressBar
|
||||
|
||||
from module.worker import DTGWorker
|
||||
from ui.components.widget import Widget
|
||||
|
||||
|
||||
class InitSettingCard(GroupHeaderCardWidget):
|
||||
chooseSignal = Signal(str, str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("初始化")
|
||||
self.setBorderRadius(8)
|
||||
|
||||
self.chooseStudentButton = PushButton("打开")
|
||||
self.chooseQuestionButton = PushButton("打开")
|
||||
|
||||
self.chooseStudentButton.setFixedWidth(120)
|
||||
self.chooseQuestionButton.setFixedWidth(120)
|
||||
|
||||
self.stuGroup = self.addGroup(FluentIcon.DOCUMENT, "学生名单", "选择学生名单文件", self.chooseStudentButton)
|
||||
self.QueGroup = self.addGroup(FluentIcon.DOCUMENT, "题库", "选择题库文件", self.chooseQuestionButton)
|
||||
|
||||
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)))
|
||||
|
||||
def choose_file(
|
||||
self,
|
||||
set_value: Callable[[str], None] = None,
|
||||
prefix: str = "",
|
||||
cb: Callable[[str], None] = None
|
||||
) -> None:
|
||||
file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Excel 文件 (*.xlsx *.xlsm);")
|
||||
if file_path and set_value:
|
||||
set_value(prefix + file_path)
|
||||
if cb:
|
||||
cb(file_path)
|
||||
|
||||
|
||||
class ExportSettingsCard(GroupHeaderCardWidget):
|
||||
startSignal = Signal()
|
||||
updateSignal = Signal(str, str)
|
||||
|
||||
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.hintIcon = IconWidget(InfoBarIcon.INFORMATION)
|
||||
self.hintLabel = BodyLabel("点击导出按钮以开始生成 👉")
|
||||
self.chooseExportDirectoryButton.setFixedWidth(120)
|
||||
self.startButton.setFixedWidth(120)
|
||||
self.exportFileNameLineEdit.setFixedWidth(360)
|
||||
self.exportFileNameLineEdit.setPlaceholderText("输入导出文件名,例如:21工程管理(1)答辩题目")
|
||||
self.bottomLayout = QHBoxLayout()
|
||||
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.dirGroup = self.addGroup(FluentIcon.FOLDER, "导出目录", "选择导出文件的目录",
|
||||
self.chooseExportDirectoryButton)
|
||||
self.fnGroup = self.addGroup(FluentIcon.DOCUMENT, "导出文件名", "输入导出文件的名称",
|
||||
self.exportFileNameLineEdit)
|
||||
self.fnGroup.setSeparatorVisible(True)
|
||||
|
||||
self.vBoxLayout.addLayout(self.bottomLayout)
|
||||
|
||||
# ==============
|
||||
self.chooseExportDirectoryButton.clicked.connect(self.choose_dir)
|
||||
self.startButton.clicked.connect(self.startSignal.emit)
|
||||
self.exportFileNameLineEdit.textChanged.connect(lambda x: self.updateSignal.emit('n', x))
|
||||
|
||||
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_export_setting_by_signal(self, path: str) -> None:
|
||||
f_dir = path[:path.rfind('/')]
|
||||
f_name = path[path.rfind('/') + 1:path.rfind('.')]
|
||||
self.dirGroup.setContent(f"当前保存的文件目录:{f_dir}")
|
||||
self.updateSignal.emit('d', f_dir)
|
||||
self.exportFileNameLineEdit.setText(f"{f_name}-答辩题目")
|
||||
self.updateSignal.emit('n', f_name)
|
||||
|
||||
|
||||
class DefenseWidget(Widget):
|
||||
def __init__(self, key: str, parent=None):
|
||||
super().__init__(key, parent)
|
||||
|
||||
self.initCard = InitSettingCard(self)
|
||||
self.exportCard = ExportSettingsCard(self)
|
||||
self.vbox = QVBoxLayout(self)
|
||||
|
||||
self.vbox.addWidget(self.initCard)
|
||||
self.vbox.addWidget(self.exportCard)
|
||||
self.vbox.addStretch(1)
|
||||
|
||||
self.infoBar = None
|
||||
self.pb = None
|
||||
|
||||
self.thread = None
|
||||
self.worker = None
|
||||
|
||||
# ===================================
|
||||
|
||||
self.input_student_filepath = None
|
||||
self.input_question_filepath = None
|
||||
self.output_filepath = None
|
||||
self.output_filename = None
|
||||
|
||||
# ====================================
|
||||
self.initCard.chooseSignal.connect(self.input_signal_receive)
|
||||
self.exportCard.updateSignal.connect(self.export_update_signal_receive)
|
||||
self.exportCard.startSignal.connect(self.start_generate)
|
||||
|
||||
def show_info_bar(self):
|
||||
self.infoBar = InfoBar(
|
||||
icon=InfoBarIcon.INFORMATION,
|
||||
title='请稍后',
|
||||
content="",
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=False,
|
||||
position=InfoBarPosition.BOTTOM,
|
||||
duration=-1,
|
||||
parent=self
|
||||
)
|
||||
self.pb = ProgressBar(self.infoBar)
|
||||
self.infoBar.addWidget(self.pb)
|
||||
self.infoBar.show()
|
||||
|
||||
def set_pb_value(self, value: int) -> None:
|
||||
if self.pb:
|
||||
self.pb.setValue(value)
|
||||
if value == 100:
|
||||
self.infoBar.close()
|
||||
self.infoBar = InfoBar.success(
|
||||
title='成功!',
|
||||
content="正在打开文件...",
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.BOTTOM,
|
||||
duration=5000,
|
||||
parent=self
|
||||
)
|
||||
self.pb = None
|
||||
self.exportCard.startButton.setEnabled(True)
|
||||
|
||||
def enable_start_check(func: Callable):
|
||||
@wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
result = func(self, *args, **kwargs)
|
||||
|
||||
fields = [
|
||||
self.input_student_filepath,
|
||||
self.input_question_filepath,
|
||||
self.output_filepath,
|
||||
self.output_filename
|
||||
]
|
||||
if all(fields):
|
||||
self.exportCard.startButton.setEnabled(True)
|
||||
else:
|
||||
self.exportCard.startButton.setEnabled(False)
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
@enable_start_check
|
||||
def set_value(self, key: str, value: str) -> None:
|
||||
if key == "input_student_filepath":
|
||||
self.input_student_filepath = value
|
||||
elif key == "input_question_filepath":
|
||||
self.input_question_filepath = value
|
||||
elif key == "output_filepath":
|
||||
self.output_filepath = value
|
||||
elif key == "output_filename":
|
||||
self.output_filename = value
|
||||
setattr(self, key, value)
|
||||
|
||||
def input_signal_receive(self, s_type: Literal['s', 'q'], value: str):
|
||||
if s_type == "s":
|
||||
self.set_value("input_student_filepath", value)
|
||||
self.exportCard.update_export_setting_by_signal(value)
|
||||
elif s_type == "q":
|
||||
self.set_value("input_question_filepath", value)
|
||||
|
||||
def export_update_signal_receive(self, s_type: Literal['d', 'n'], value: str):
|
||||
if s_type == "d":
|
||||
self.set_value("output_filepath", value)
|
||||
elif s_type == "n":
|
||||
self.set_value("output_filename", value)
|
||||
|
||||
def start_generate(self):
|
||||
self.thread = QThread()
|
||||
self.worker = DTGWorker(
|
||||
self.input_student_filepath,
|
||||
self.input_question_filepath,
|
||||
self.output_filepath,
|
||||
self.output_filename
|
||||
)
|
||||
self.worker.moveToThread(self.thread)
|
||||
|
||||
self.show_info_bar()
|
||||
self.exportCard.startButton.setEnabled(False)
|
||||
|
||||
# 线程启动与信号连接
|
||||
self.thread.started.connect(self.worker.run)
|
||||
self.worker.progress.connect(self.set_pb_value)
|
||||
|
||||
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.start()
|
||||
|
||||
def clear_thread_worker_refs(self):
|
||||
self.thread = None
|
||||
self.worker = None
|
||||
140
ui/pyui/main.py
140
ui/pyui/main.py
@@ -1,140 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'main.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.9.0
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
|
||||
QLabel, QLineEdit, QMainWindow, QPushButton,
|
||||
QSizePolicy, QSpacerItem, QStatusBar, QWidget)
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
if not MainWindow.objectName():
|
||||
MainWindow.setObjectName(u"MainWindow")
|
||||
MainWindow.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||
MainWindow.resize(500, 200)
|
||||
MainWindow.setMinimumSize(QSize(500, 200))
|
||||
MainWindow.setMaximumSize(QSize(500, 200))
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout_2 = QGridLayout(self.centralwidget)
|
||||
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
||||
self.horizontalLayout_3 = QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.label = QLabel(self.centralwidget)
|
||||
self.label.setObjectName(u"label")
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.label)
|
||||
|
||||
self.student_list_path = QLineEdit(self.centralwidget)
|
||||
self.student_list_path.setObjectName(u"student_list_path")
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.student_list_path)
|
||||
|
||||
self.select_student_list = QPushButton(self.centralwidget)
|
||||
self.select_student_list.setObjectName(u"select_student_list")
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.select_student_list)
|
||||
|
||||
|
||||
self.gridLayout_2.addLayout(self.horizontalLayout_3, 0, 0, 1, 1)
|
||||
|
||||
self.groupBox = QGroupBox(self.centralwidget)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.gridLayout = QGridLayout(self.groupBox)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label_2 = QLabel(self.groupBox)
|
||||
self.label_2.setObjectName(u"label_2")
|
||||
self.label_2.setMinimumSize(QSize(40, 0))
|
||||
self.label_2.setMaximumSize(QSize(40, 16777215))
|
||||
|
||||
self.horizontalLayout.addWidget(self.label_2)
|
||||
|
||||
self.output_path = QLineEdit(self.groupBox)
|
||||
self.output_path.setObjectName(u"output_path")
|
||||
|
||||
self.horizontalLayout.addWidget(self.output_path)
|
||||
|
||||
self.select_output_dir = QPushButton(self.groupBox)
|
||||
self.select_output_dir.setObjectName(u"select_output_dir")
|
||||
|
||||
self.horizontalLayout.addWidget(self.select_output_dir)
|
||||
|
||||
|
||||
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
|
||||
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||
self.label_3 = QLabel(self.groupBox)
|
||||
self.label_3.setObjectName(u"label_3")
|
||||
self.label_3.setMinimumSize(QSize(40, 0))
|
||||
self.label_3.setMaximumSize(QSize(40, 16777215))
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_3)
|
||||
|
||||
self.output_filename = QLineEdit(self.groupBox)
|
||||
self.output_filename.setObjectName(u"output_filename")
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.output_filename)
|
||||
|
||||
|
||||
self.gridLayout.addLayout(self.horizontalLayout_2, 1, 0, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout_2.addWidget(self.groupBox, 1, 0, 1, 1)
|
||||
|
||||
self.horizontalLayout_4 = QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
|
||||
self.horizontalLayout_4.addItem(self.horizontalSpacer)
|
||||
|
||||
self.edit_topics = QPushButton(self.centralwidget)
|
||||
self.edit_topics.setObjectName(u"edit_topics")
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.edit_topics)
|
||||
|
||||
self.start = QPushButton(self.centralwidget)
|
||||
self.start.setObjectName(u"start")
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.start)
|
||||
|
||||
|
||||
self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 0, 1, 1)
|
||||
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.statusbar = QStatusBar(MainWindow)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
MainWindow.setStatusBar(self.statusbar)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
||||
self.label.setText(QCoreApplication.translate("MainWindow", u"\u5b66\u751f\u540d\u5355", None))
|
||||
self.select_student_list.setText(QCoreApplication.translate("MainWindow", u"\u9009\u62e9", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("MainWindow", u"\u5bfc\u51fa\u8bbe\u7f6e", None))
|
||||
self.label_2.setText(QCoreApplication.translate("MainWindow", u"\u76ee \u5f55", None))
|
||||
self.select_output_dir.setText(QCoreApplication.translate("MainWindow", u"\u9009\u62e9", None))
|
||||
self.label_3.setText(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6\u540d", None))
|
||||
self.edit_topics.setText(QCoreApplication.translate("MainWindow", u"\u7f16\u8f91\u9898\u5e93", None))
|
||||
self.start.setText(QCoreApplication.translate("MainWindow", u"\u5bfc\u51fa", None))
|
||||
# retranslateUi
|
||||
|
||||
Reference in New Issue
Block a user