修改界面

This commit is contained in:
2025-05-20 02:59:58 +08:00
parent 83b3790e8b
commit 9ca61d5092
13 changed files with 394 additions and 499 deletions

9
ui/components/widget.py Normal file
View File

@@ -0,0 +1,9 @@
from PySide6.QtWidgets import QFrame
class Widget(QFrame):
def __init__(self, key: str, parent=None):
super().__init__(parent=parent)
# 必须给子界面设置全局唯一的对象名
self.setObjectName(key.replace(' ', '-'))

View File

@@ -1,102 +1,23 @@
import os
import platform
import subprocess
from pathlib import Path
from qfluentwidgets import FluentIcon, MSFluentWindow, NavigationItemPosition
from PySide6.QtCore import QObject, QThread, Signal
from PySide6.QtWidgets import QMainWindow, QFileDialog
from module.doc import DocPaper
from module.schema import Course, Student, Question
from ui.pyui.main import Ui_MainWindow
from utils.function import resource_path
from ui.pyui.about_ui import AboutWidget
from ui.pyui.defense_ui import DefenseWidget
class Worker(QObject):
progress = Signal(str)
finished = Signal()
def __init__(self, input_filepath: str, output_filepath: str, output_filename: str):
super().__init__()
self.input_filepath = input_filepath
self.output_filepath = output_filepath
self.output_filename = output_filename
def run(self):
self.progress.emit("第一步:正在读取课程信息...")
course = Course.load_from_xls(self.input_filepath)
self.progress.emit("第二步:正在读取学生信息...")
students = Student.load_from_xls(self.input_filepath)
self.progress.emit("第三步:正在读取题目信息...")
questions = Question.load_from_csv(str(Path(os.environ["APPDATA"]) / "dtg" / "questions.csv"))
d = DocPaper(self.output_filename, template_path=resource_path("template/template.docx"))
for student in students:
self.progress.emit(f"第四步:({student.no}/{len(students)})正在处理学生:{student.name},学号:{student.so}")
student.pick_question(questions)
d.add_paper(course, student)
self.progress.emit("第五步:正在保存文件...")
d.save(self.output_filepath)
self.progress.emit("第六步:文件保存成功!")
os.startfile(Path(self.output_filepath) / f"{self.output_filename}.docx")
class MainWindow(QMainWindow, Ui_MainWindow):
class MainWindow(MSFluentWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle("答辩题目生成器")
self.select_student_list.clicked.connect(self.choose_student_list)
self.select_output_dir.clicked.connect(self.choose_output_dir)
self.edit_topics.clicked.connect(self.edit_questions)
self.start.clicked.connect(self.start_generate)
self.homeInterface = DefenseWidget('Defense Interface', self)
self.aboutInterface = AboutWidget('About Interface', self)
def on_button_clicked(self):
self.statusBar().showMessage("这是状态栏信息")
self.initNavigation()
self.initWindow()
def choose_student_list(self):
file_path, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Excel 文件 (*.xlsx);")
if file_path:
self.student_list_path.setText(file_path)
def initNavigation(self):
self.addSubInterface(self.homeInterface, FluentIcon.HOME, '首页')
self.addSubInterface(self.aboutInterface, FluentIcon.INFO, '关于', position=NavigationItemPosition.BOTTOM)
input_dir_path = file_path[:file_path.rfind('/')]
default_output_filename = file_path[file_path.rfind('/') + 1:file_path.rfind('-点名册')]
self.output_path.setText(input_dir_path)
self.output_filename.setText(default_output_filename)
def choose_output_dir(self):
dir_path = QFileDialog.getExistingDirectory(self, "选择文件夹", "")
if dir_path:
self.output_path.setText(dir_path)
def edit_questions(self):
csv_path = Path(os.environ["APPDATA"]) / "dtg" / "questions.csv"
if platform.system() == "Windows":
os.startfile(csv_path.resolve())
elif platform.system() == "Darwin": # macOS
subprocess.run(["open", csv_path.resolve()])
else: # Linux
subprocess.run(["xdg-open", csv_path.resolve()])
self.update_statusbar("已打开题目文件,请在外部程序编辑后保存。")
def start_generate(self):
self.thread = QThread()
self.worker = Worker(self.student_list_path.text(), self.output_path.text(), self.output_filename.text())
self.worker.moveToThread(self.thread)
# 线程启动与信号连接
self.thread.started.connect(self.worker.run)
self.worker.progress.connect(self.update_statusbar)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
# 启动线程
self.thread.start()
def update_statusbar(self, message):
self.statusBar().showMessage(message)
def initWindow(self):
self.resize(900, 700)
self.setWindowTitle('答辩题目生成器')

View File

@@ -1,159 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModality::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>200</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>500</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>500</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>学生名单</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="student_list_path"/>
</item>
<item>
<widget class="QPushButton" name="select_student_list">
<property name="text">
<string>选择</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>导出设置</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>目 录</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="output_path"/>
</item>
<item>
<widget class="QPushButton" name="select_output_dir">
<property name="text">
<string>选择</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>文件名</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="output_filename"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="edit_topics">
<property name="text">
<string>编辑题库</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="start">
<property name="text">
<string>导出</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

49
ui/pyui/about_ui.py Normal file
View 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
View 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

View File

@@ -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