diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b44cdf..5b31beb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ else() set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/release) endif() -find_package(Qt6 REQUIRED COMPONENTS Quick Svg Network HttpServer Concurrent) +find_package(Qt6 REQUIRED COMPONENTS Quick Svg Network HttpServer Concurrent LinguistTools) if(${Qt6_VERSION} VERSION_GREATER_EQUAL "6.3") qt_standard_project_setup() @@ -106,6 +106,22 @@ qt_add_qml_module(SAST_Evento_Desktop SOURCES ${SOURCE_IMPORT_FILES} ) +# 多语言配置 +list(APPEND TS_FILES ${CMAKE_SOURCE_DIR}/translations/SAST_Evento_en.ts) +set_source_files_properties(${TS_FILES} + PROPERTIES OUTPUT_LOCATION "${CMAKE_SOURCE_DIR}/translations") +file(GLOB_RECURSE QML_FILES + ${CMAKE_SOURCE_DIR}/qml/*.qml +) +qt_add_lupdate(SAST_Evento_Desktop + TS_FILES ${TS_FILES} + SOURCES ${QML_FILES} +) +qt_add_lrelease(SAST_Evento_Desktop + TS_FILES ${TS_FILES} + QM_FILES_OUTPUT_VARIABLE QM_FILES +) + set_property(TARGET ${PROJECT_NAME} PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/.cmake/Info.plist.in") diff --git a/SAST_Evento.qrc b/SAST_Evento.qrc index d8cd0be..bbc436f 100644 --- a/SAST_Evento.qrc +++ b/SAST_Evento.qrc @@ -66,5 +66,6 @@ app.icns qml/page/T_LessonPic.qml res/image/department/SRD_lesson_pic_bg.jpg + translations/SAST_Evento_en.qm diff --git a/qml/page/T_Settings.qml b/qml/page/T_Settings.qml index d53d168..0e0a015 100644 --- a/qml/page/T_Settings.qml +++ b/qml/page/T_Settings.qml @@ -127,8 +127,8 @@ FluScrollablePage { delegate: FluRadioButton { checked: settings.langMode === modelData text: lang_text - clickListener: function () { - settings.langMode = langSetting[index] + clickListener:function () { + settings.langMode = langSetting.model[index] Lang.changeLangMode(index) } } @@ -178,7 +178,7 @@ FluScrollablePage { target: CheckUpdate function onCheckSuccessEvent(version, description) { btn_progress.progress = 1 - if (version === appInfo.version) + if (version === AppInfo.version) showInfo(lang.lang_is_currently_latest_version, 4000) } } diff --git a/qml/window/LoginWindow.qml b/qml/window/LoginWindow.qml index e6e1ffa..7365ddf 100644 --- a/qml/window/LoginWindow.qml +++ b/qml/window/LoginWindow.qml @@ -8,7 +8,7 @@ import org.wangwenx190.FramelessHelper FluWindow { id: window - title: lang.lang_login + title: qsTr("登录") width: 278 height: 378 fixSize: true @@ -52,7 +52,7 @@ FluWindow { target: LoginController function onLoadPermissionErrorEvent(message) { hideLoading() - showError(lang.lang_error + message, 4000) + showError(qsTr("登录失败:") + message, 4000) } } @@ -60,10 +60,9 @@ FluWindow { target: LoginController function onLoginFailed(reason) { hideLoading() - system_tray.showMessage(lang.lang_login_failed, - lang.lang_error + reason) + system_tray.showMessage(qsTr("登录失败"), qsTr("错误:") + reason) window.requestActivate() - showError(lang.lang_login_failed, 4000) + showError(qsTr("登录失败"), 4000) } } @@ -93,7 +92,7 @@ FluWindow { tooltip: "SAST Evento" menu: Menu { MenuItem { - text: lang.lang_exit + text: qsTr("退出") onTriggered: { window.deleteWindow() FluApp.closeApp() @@ -111,7 +110,7 @@ FluWindow { FluButton { id: btn_login - text: lang.lang_use_link + text: qsTr(" 使用 Link 登入") font.pixelSize: 16 font.bold: true textColor: Qt.rgba(250 / 255, 250 / 255, 250 / 255, 1) @@ -146,7 +145,7 @@ FluWindow { FluIconButton { id: btn_visitor - text: lang.lang_guest_login + text: qsTr("访客登录") iconSource: FluentIcons.GuestUser display: Button.TextBesideIcon anchors { @@ -162,7 +161,7 @@ FluWindow { } FluText { - text: lang.lang_by_cpp + appInfo.version + text: qsTr("NJUPT SAST C++组开发\n") + AppInfo.version color: FluColors.Grey100 font: FluTextStyle.Caption horizontalAlignment: Text.AlignHCenter diff --git a/qml/window/MainWindow.qml b/qml/window/MainWindow.qml index 96600ec..555102e 100644 --- a/qml/window/MainWindow.qml +++ b/qml/window/MainWindow.qml @@ -61,7 +61,7 @@ FluWindow { | FluContentDialogType.PositiveButton onNegativeClicked: { window.hide() - system_tray.showMessage(lang.lang_hint, lang.lang_hint_info) + system_tray.showMessage(qsTr("提示"), qsTr("SAST Evento已隐藏至托盘,点击图标可再次激活窗口。")) } positiveText: lang.lang_exit neutralText: lang.lang_cancel diff --git a/src/lang/Lang.h b/src/lang/Lang.h index 0e1d933..4fac8a3 100644 --- a/src/lang/Lang.h +++ b/src/lang/Lang.h @@ -1,14 +1,23 @@ #ifndef LANG_H #define LANG_H -#include +#include #include class Lang : public QObject { Q_OBJECT QML_NAMED_ELEMENT(Lang) QML_SINGLETON - +private: + QTranslator* translator = nullptr; +public: + Lang() { + QLocale::setDefault(QLocale::Chinese); + } + ~Lang() { + if (translator) + translator->deleteLater(); + } public: enum LanguageMode { System, @@ -17,7 +26,27 @@ class Lang : public QObject { }; Q_ENUM(LanguageMode) public: - Q_INVOKABLE void changeLangMode(LanguageMode) {} + Q_INVOKABLE void changeLangMode(LanguageMode mode) { + QLocale next; + switch (mode) { + case System: next = QLocale::system();break; + case Chinese: next = QLocale::Chinese;break; + case English: next = QLocale::English;break; + } + if (next.language() == QLocale()) + return; + switch (next.language()) { + case QLocale::Chinese:QCoreApplication::removeTranslator(translator);break; + case QLocale::English: + if (!translator) { + translator = new QTranslator(); + translator->load("SAST_Evento_en.qm", ":/translations"); + } + QCoreApplication::installTranslator(translator); + break; + } + QLocale::setDefault(next); + } }; #endif // LANG_H diff --git a/translations/SAST_Evento_en.ts b/translations/SAST_Evento_en.ts new file mode 100644 index 0000000..a8448ff --- /dev/null +++ b/translations/SAST_Evento_en.ts @@ -0,0 +1,95 @@ + + + + + LoginWindow + + + 登录 + + + + + 登录失败: + + + + + + 登录失败 + + + + + 错误: + + + + + 退出 + + + + + 使用 Link 登入 + + + + + 访客登录 + + + + + NJUPT SAST C++组开发 + + + + + + MainWindow + + + 提示 + HINT + + + + SAST Evento已隐藏至托盘,点击图标可再次激活窗口。 + SAST Evento is hidden in the system tray. Click the icon to activate the window. + + + + T_LessonPic + + + %1 + + + + + 第%1周 + + + + + 授课课表 + + + + + 时间:%1 + + + + + 地点:%1 + + + + + 主题:%1 + + + +