diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 73e9a56..6399891 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -38,7 +38,9 @@ set(ts_files i18n/${PROJECT_NAME}_zh_CN.ts i18n/${PROJECT_NAME}_en_US.ts) # Source and QML files set(sources_files example.cpp) -set(qml_files example.qml about.qml components/RibbonMessageListViewExample.qml pages/SettingsMenuPage.qml components/TabBar.qml) +set(qml_files example.qml about.qml SplashScreen.qml + components/RibbonMessageListViewExample.qml + pages/SettingsMenuPage.qml components/TabBar.qml) set(qml_prefix "qml/Qt${QT_VERSION_MAJOR}/") list(TRANSFORM qml_files PREPEND ${qml_prefix}) diff --git a/example/example.cpp b/example/example.cpp index bf127c0..78d7a03 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) qml_static_register_types_RibbonUI(); #endif #endif - const QUrl url("qrc:/qt/qml/RibbonUIAPP/example.qml"); + const QUrl url("qrc:/qt/qml/RibbonUIAPP/SplashScreen.qml"); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) diff --git a/example/i18n/RibbonUIAPP_en_US.ts b/example/i18n/RibbonUIAPP_en_US.ts index 20e1b3c..358c9c4 100644 --- a/example/i18n/RibbonUIAPP_en_US.ts +++ b/example/i18n/RibbonUIAPP_en_US.ts @@ -163,6 +163,27 @@ + + SplashScreen + + + + Example App + + + + + + A example for users to use RibbonUI. + + + + + + Loading...Remain %1s... + + + TabBar @@ -503,7 +524,7 @@ - + About @@ -528,34 +549,37 @@ - + + Home - + + File - + + Search - + Account - + Settings diff --git a/example/i18n/RibbonUIAPP_zh_CN.ts b/example/i18n/RibbonUIAPP_zh_CN.ts index cbc9408..a884129 100644 --- a/example/i18n/RibbonUIAPP_zh_CN.ts +++ b/example/i18n/RibbonUIAPP_zh_CN.ts @@ -163,6 +163,27 @@ 隐藏 + + SplashScreen + + + + Example App + 示例程序 + + + + + A example for users to use RibbonUI. + 一个为了让用户学会使用RibbonUI的示例程序。 + + + + + Loading...Remain %1s... + 加载中...剩余 %1秒... + + TabBar @@ -503,7 +524,7 @@ - + About @@ -528,34 +549,37 @@ 测试项目 1 - + + Home 主页 - + + File 文件 - + + Search 搜索 - + Account 账户 - + Settings 设置 diff --git a/example/qml/Qt5/SplashScreen.qml b/example/qml/Qt5/SplashScreen.qml new file mode 100644 index 0000000..4fdba9d --- /dev/null +++ b/example/qml/Qt5/SplashScreen.qml @@ -0,0 +1,26 @@ +import QtQuick 2.15 +import RibbonUI 1.1 + +RibbonSplashScreen { + id: root + homeUrl: "qrc:/qt/qml/RibbonUIAPP/example.qml" + delayMS: 10000 + contentArgs: { + "implicitHeight": 250, + "implicitWidth": 450, + "titleText": qsTr("Example App"), + "subTitleText": qsTr("A example for users to use RibbonUI.") + } + + Timer{ + interval: 1000 + triggeredOnStart: true + repeat: true + running: true + property int remainSeconds: root.delayMS / 1000 + onTriggered: { + remainSeconds -= 1 + root.showLoadingLog(qsTr("Loading...Remain %1s...").arg(remainSeconds), {}) + } + } +} diff --git a/example/qml/Qt6/SplashScreen.qml b/example/qml/Qt6/SplashScreen.qml new file mode 100644 index 0000000..915d8b1 --- /dev/null +++ b/example/qml/Qt6/SplashScreen.qml @@ -0,0 +1,26 @@ +import QtQuick +import RibbonUI + +RibbonSplashScreen { + id: root + homeUrl: "qrc:/qt/qml/RibbonUIAPP/example.qml" + delayMS: 10000 + contentArgs: { + "implicitHeight": 250, + "implicitWidth": 450, + "titleText": qsTr("Example App"), + "subTitleText": qsTr("A example for users to use RibbonUI.") + } + + Timer{ + interval: 1000 + triggeredOnStart: true + repeat: true + running: true + property int remainSeconds: root.delayMS / 1000 + onTriggered: { + remainSeconds -= 1 + root.showLoadingLog(qsTr("Loading...Remain %1s...").arg(remainSeconds), {}) + } + } +} diff --git a/lib_source/CMakeLists.txt b/lib_source/CMakeLists.txt index 6d1fe9a..f3a0375 100644 --- a/lib_source/CMakeLists.txt +++ b/lib_source/CMakeLists.txt @@ -51,7 +51,9 @@ set(qml_files RibbonRadioButton.qml RibbonBackStageMenuItem.qml RibbonTourItem.qml RibbonObject.qml RibbonProgressBar.qml RibbonProgressRing.qml RibbonBusyBar.qml RibbonBusyRing.qml RibbonPageIndicator.qml - RibbonMessageBar.qml RibbonMessageBarGroup.qml) + RibbonMessageBar.qml RibbonMessageBarGroup.qml RibbonSplashScreen.qml + RibbonSplashScreenContent.qml +) # Set the QML prefix path set(qml_prefix "qml/Qt${QT_VERSION_MAJOR}/") diff --git a/lib_source/i18n/RibbonUI_en_US.ts b/lib_source/i18n/RibbonUI_en_US.ts index 16cd140..3ed214f 100644 --- a/lib_source/i18n/RibbonUI_en_US.ts +++ b/lib_source/i18n/RibbonUI_en_US.ts @@ -173,6 +173,15 @@ + + RibbonSplashScreenContent + + + + Loading... + + + RibbonSwitchButton @@ -358,33 +367,33 @@ RibbonWindow - - - - Quit - - - - - - Minimize - - - Cancel + Quit - Do you want to close this window? + Minimize + Cancel + + + + + + Do you want to close this window? + + + + + Please note diff --git a/lib_source/i18n/RibbonUI_zh_CN.ts b/lib_source/i18n/RibbonUI_zh_CN.ts index a1ee699..44cd9b1 100644 --- a/lib_source/i18n/RibbonUI_zh_CN.ts +++ b/lib_source/i18n/RibbonUI_zh_CN.ts @@ -173,6 +173,15 @@ 加载中 + + RibbonSplashScreenContent + + + + Loading... + 加载中... + + RibbonSwitchButton @@ -360,32 +369,32 @@ RibbonWindow - - + + Quit 退出 - - + + Minimize 最小化 - - + + Cancel 取消 - - + + Do you want to close this window? 需要关闭窗口吗? - - + + Please note 请注意 diff --git a/lib_source/qml/Qt5/RibbonSplashScreen.qml b/lib_source/qml/Qt5/RibbonSplashScreen.qml new file mode 100644 index 0000000..a28934f --- /dev/null +++ b/lib_source/qml/Qt5/RibbonSplashScreen.qml @@ -0,0 +1,145 @@ +import QtQuick 2.15 +import RibbonUI 1.1 +import QtQuick.Layouts 1.11 +import QtQuick.Controls 2.15 +import QtQuick.Window 2.15 +import QWindowKit 1.0 + +Window { + id: root + required property string homeUrl + width: container.width + height: container.height + color: "transparent" + property real delayMS: 2000 + property alias contentArgs: container.args + property var homeArgs: ({}) + property string contentSource: "RibbonSplashScreenContent.qml" + property var contentItems: undefined + property bool blurBehindWindow : Qt.platform.os === 'windows' && !RibbonUI.isWin11 ? false : true + + signal showLoadingLog(log: string, others: var) + signal finished() + + ColumnLayout{ + id: container + spacing: 10 + property var args: ({}) + Loader{ + id: loader + sourceComponent: contentSource ? undefined : contentItems + source: contentSource ? contentSource : "" + onLoaded: { + root.showLoadingLog.connect(item.dealWithLog) + if (!Object.keys(container.args).length) + return + else if(Object.keys(container.args).length){ + for (let arg in container.args){ + item[arg] = container.args[arg] + } + } + else{ + console.error("RibbonSplashScreen: Arguments error, please check.") + } + } + } + } + + QtObject{ + id: internal + property bool isComponentReady: false + property var component + property var home + + onIsComponentReadyChanged: { + if(isComponentReady) + timer.running = true + } + + function dealWithHome(component, home){ + if (!(home.object instanceof Window)) + { + console.error("RibbonSplashScreen: Error loading Home because instance is not Window.") + return + } + home = home.object + home.onClosing.connect(function() { + if(!home.visible){ + component.destroy() + home.destroy() + } + }); + home.raise() + home.requestActivate() + } + + function configHome(){ + let home = internal.component.incubateObject(null, root.homeArgs) + if (home.status !== Component.Ready) { + home.onStatusChanged = function(status) { + if (status === Component.Ready) { + console.debug("RibbonSplashScreen:", "Object", home.object, "is now ready.") + dealWithHome(internal.component, home) + } + } + } else { + console.debug("RibbonSplashScreen:", "Object", home.object, "is ready immediately.") + dealWithHome(internal.component, home) + } + } + } + + Timer{ + id: timer + interval: root.delayMS + repeat: false + running: false + onTriggered: { + internal.isComponentReady = false + root.visible = false + internal.configHome() + finished() + } + } + + WindowAgent { + id: windowAgent + } + + Component.onCompleted: { + windowAgent.setup(root) + if (Qt.platform.os === 'windows') + { + windowAgent.setWindowAttribute("dwm-blur", blurBehindWindow) + } + if(Qt.platform.os === "osx") + { + windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.isDarkMode ? "dark" : "light" : "none") + } + root.flags |= Qt.WindowStaysOnTopHint + PlatformSupport.showSystemTitleBtns(root, false) + root.visible = true + windowAgent.centralize() + raise() + requestActivate() + + const component = Qt.createComponent(root.homeUrl, Component.Asynchronous, null) + + if(component.status !== Component.Ready){ + component.statusChanged.connect(function(){ + if (component.status === Component.Ready) { + console.debug("RibbonSplashScreen:", "Component", component, "is now ready.") + internal.component = component + internal.isComponentReady = true + } else if (component.status === Component.Error) { + console.error("RibbonSplashScreen: Error loading Window Component:", component.errorString()) + } + }) + } + else{ + console.debug("RibbonSplashScreen:", component, "is ready immediately.") + internal.component = component + internal.isComponentReady = true + } + } +} diff --git a/lib_source/qml/Qt5/RibbonSplashScreenContent.qml b/lib_source/qml/Qt5/RibbonSplashScreenContent.qml new file mode 100644 index 0000000..d482d3b --- /dev/null +++ b/lib_source/qml/Qt5/RibbonSplashScreenContent.qml @@ -0,0 +1,165 @@ +import QtQuick 2.15 +import RibbonUI 1.1 +import QtQuick.Layouts 1.11 +import QtQuick.Controls 2.15 +import QtQuick.Window 2.15 + +RibbonRectangle { + id: control + + property var dealWithLog: showLog + property string picSource: "qrc:/qt/qml/RibbonUI/resources/imgs/icon.png" + property string labelText: "Dylan Liu's Lab" + property string titleText: "RibbonUI" + property string subTitleText: "A lightweight UI framework." + + color: { + if (Window.window.blurBehindWindow) { + return "transparent" + } + if (RibbonTheme.isDarkMode) { + return '#2C2B29' + } + return '#FFFFFF' + } + implicitHeight: Math.max(250, btn_layout.height + title_layout.height + log_text.height + btn_layout.anchors.topMargin * 2) + implicitWidth: Math.max(450, title_layout.width + btn_layout.anchors.topMargin * 2) + radius: 20 + + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + + RowLayout{ + id: btn_layout + layoutDirection: Qt.platform.os === 'osx' ? Qt.RightToLeft : Qt.LeftToRight + anchors{ + top:parent.top + topMargin: 8 + right: Qt.platform.os === 'osx' ? undefined : parent.right + rightMargin: Qt.platform.os === 'osx' ? undefined : anchors.topMargin + left: Qt.platform.os === 'osx' ? parent.left : undefined + leftMargin: Qt.platform.os === 'osx' ? anchors.topMargin : undefined + } + RibbonButton{ + showBg: false + showHoveredBg: false + iconSource: RibbonIcons.Subtract + onClicked: Window.window.visibility = Window.Minimized + } + RibbonButton{ + showBg: false + showHoveredBg: false + iconSource: RibbonIcons.Dismiss + onClicked: Qt.quit() + } + } + RowLayout{ + anchors{ + top: parent.top + topMargin: btn_layout.anchors.topMargin + right: Qt.platform.os !== 'osx' ? undefined : parent.right + rightMargin: Qt.platform.os !== 'osx' ? undefined : anchors.topMargin + left: Qt.platform.os !== 'osx' ? parent.left : undefined + leftMargin: Qt.platform.os !== 'osx' ? anchors.topMargin : undefined + } + Image { + id: pic + source: control.picSource + visible: typeof(control.picSource) === "string" + fillMode:Image.PreserveAspectFit + mipmap: true + autoTransform: true + Layout.preferredHeight: label_text.visible ? label_text.contentHeight : 16 + Layout.preferredWidth: Layout.preferredHeight + Layout.alignment: Qt.AlignVCenter + } + Text { + id: label_text + text: control.labelText + Layout.alignment: Qt.AlignVCenter + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 16 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + } + ColumnLayout{ + id: title_layout + anchors.centerIn: parent + spacing: -5 + Text { + id: title_text + text: control.titleText + Layout.alignment: Qt.AlignHCenter + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 50 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + Text { + id: subtitle_text + text: control.subTitleText + Layout.alignment: Qt.AlignHCenter + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 15 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + RibbonBusyBar{ + Layout.topMargin: btn_layout.anchors.topMargin - title_layout.spacing + running: true + barWidth: control.width - btn_layout.anchors.topMargin * 4 + } + } + + Text { + id: log_text + anchors{ + left: parent.left + leftMargin: btn_layout.anchors.topMargin + bottom: parent.bottom + bottomMargin: btn_layout.anchors.topMargin + } + text: qsTr("Loading...") + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 10 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + + function showLog(log, others){ + log_text.text = log + } +} diff --git a/lib_source/qml/Qt6/RibbonSplashScreen.qml b/lib_source/qml/Qt6/RibbonSplashScreen.qml new file mode 100644 index 0000000..cc800b8 --- /dev/null +++ b/lib_source/qml/Qt6/RibbonSplashScreen.qml @@ -0,0 +1,145 @@ +import QtQuick +import RibbonUI +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Window +import QWindowKit + +Window { + id: root + required property string homeUrl + width: container.width + height: container.height + color: "transparent" + property real delayMS: 2000 + property alias contentArgs: container.args + property var homeArgs: ({}) + property string contentSource: "RibbonSplashScreenContent.qml" + property var contentItems: undefined + property bool blurBehindWindow : Qt.platform.os === 'windows' && !RibbonUI.isWin11 ? false : true + + signal showLoadingLog(log: string, others: var) + signal finished() + + ColumnLayout{ + id: container + spacing: 10 + property var args: ({}) + Loader{ + id: loader + sourceComponent: contentSource ? undefined : contentItems + source: contentSource ? contentSource : "" + onLoaded: { + root.showLoadingLog.connect(item.dealWithLog) + if (!Object.keys(container.args).length) + return + else if(Object.keys(container.args).length){ + for (let arg in container.args){ + item[arg] = container.args[arg] + } + } + else{ + console.error("RibbonSplashScreen: Arguments error, please check.") + } + } + } + } + + QtObject{ + id: internal + property bool isComponentReady: false + property var component + property var home + + onIsComponentReadyChanged: { + if(isComponentReady) + timer.running = true + } + + function dealWithHome(component, home){ + if (!(home.object instanceof Window)) + { + console.error("RibbonSplashScreen: Error loading Home because instance is not Window.") + return + } + home = home.object + home.onClosing.connect(function() { + if(!home.visible){ + component.destroy() + home.destroy() + } + }); + home.raise() + home.requestActivate() + } + + function configHome(){ + let home = internal.component.incubateObject(null, root.homeArgs) + if (home.status !== Component.Ready) { + home.onStatusChanged = function(status) { + if (status === Component.Ready) { + console.debug("RibbonSplashScreen:", "Object", home.object, "is now ready.") + dealWithHome(internal.component, home) + } + } + } else { + console.debug("RibbonSplashScreen:", "Object", home.object, "is ready immediately.") + dealWithHome(internal.component, home) + } + } + } + + Timer{ + id: timer + interval: root.delayMS + repeat: false + running: false + onTriggered: { + internal.isComponentReady = false + root.visible = false + internal.configHome() + finished() + } + } + + WindowAgent { + id: windowAgent + } + + Component.onCompleted: { + windowAgent.setup(root) + if (Qt.platform.os === 'windows') + { + windowAgent.setWindowAttribute("dwm-blur", blurBehindWindow) + } + if(Qt.platform.os === "osx") + { + windowAgent.setWindowAttribute("blur-effect", blurBehindWindow ? RibbonTheme.isDarkMode ? "dark" : "light" : "none") + } + root.flags |= Qt.WindowStaysOnTopHint + PlatformSupport.showSystemTitleBtns(root, false) + root.visible = true + windowAgent.centralize() + raise() + requestActivate() + + const component = Qt.createComponent(root.homeUrl, Component.Asynchronous, null) + + if(component.status !== Component.Ready){ + component.statusChanged.connect(function(){ + if (component.status === Component.Ready) { + console.debug("RibbonSplashScreen:", "Component", component, "is now ready.") + internal.component = component + internal.isComponentReady = true + } else if (component.status === Component.Error) { + console.error("RibbonSplashScreen: Error loading Window Component:", component.errorString()) + } + }) + } + else{ + console.debug("RibbonSplashScreen:", component, "is ready immediately.") + internal.component = component + internal.isComponentReady = true + } + } +} diff --git a/lib_source/qml/Qt6/RibbonSplashScreenContent.qml b/lib_source/qml/Qt6/RibbonSplashScreenContent.qml new file mode 100644 index 0000000..790fa6d --- /dev/null +++ b/lib_source/qml/Qt6/RibbonSplashScreenContent.qml @@ -0,0 +1,165 @@ +import QtQuick +import RibbonUI +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Window + +RibbonRectangle { + id: control + + property var dealWithLog: showLog + property string picSource: "qrc:/qt/qml/RibbonUI/resources/imgs/icon.png" + property string labelText: "Dylan Liu's Lab" + property string titleText: "RibbonUI" + property string subTitleText: "A lightweight UI framework." + + color: { + if (Window.window.blurBehindWindow) { + return "transparent" + } + if (RibbonTheme.isDarkMode) { + return '#2C2B29' + } + return '#FFFFFF' + } + implicitHeight: Math.max(250, btn_layout.height + title_layout.height + log_text.height + btn_layout.anchors.topMargin * 2) + implicitWidth: Math.max(450, title_layout.width + btn_layout.anchors.topMargin * 2) + radius: 20 + + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + + RowLayout{ + id: btn_layout + layoutDirection: Qt.platform.os === 'osx' ? Qt.RightToLeft : Qt.LeftToRight + anchors{ + top:parent.top + topMargin: 8 + right: Qt.platform.os === 'osx' ? undefined : parent.right + rightMargin: Qt.platform.os === 'osx' ? undefined : anchors.topMargin + left: Qt.platform.os === 'osx' ? parent.left : undefined + leftMargin: Qt.platform.os === 'osx' ? anchors.topMargin : undefined + } + RibbonButton{ + showBg: false + showHoveredBg: false + iconSource: RibbonIcons.Subtract + onClicked: Window.window.visibility = Window.Minimized + } + RibbonButton{ + showBg: false + showHoveredBg: false + iconSource: RibbonIcons.Dismiss + onClicked: Qt.quit() + } + } + RowLayout{ + anchors{ + top: parent.top + topMargin: btn_layout.anchors.topMargin + right: Qt.platform.os !== 'osx' ? undefined : parent.right + rightMargin: Qt.platform.os !== 'osx' ? undefined : anchors.topMargin + left: Qt.platform.os !== 'osx' ? parent.left : undefined + leftMargin: Qt.platform.os !== 'osx' ? anchors.topMargin : undefined + } + Image { + id: pic + source: control.picSource + visible: typeof(control.picSource) === "string" + fillMode:Image.PreserveAspectFit + mipmap: true + autoTransform: true + Layout.preferredHeight: label_text.visible ? label_text.contentHeight : 16 + Layout.preferredWidth: Layout.preferredHeight + Layout.alignment: Qt.AlignVCenter + } + Text { + id: label_text + text: control.labelText + Layout.alignment: Qt.AlignVCenter + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 16 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + } + ColumnLayout{ + id: title_layout + anchors.centerIn: parent + spacing: -5 + Text { + id: title_text + text: control.titleText + Layout.alignment: Qt.AlignHCenter + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 50 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + Text { + id: subtitle_text + text: control.subTitleText + Layout.alignment: Qt.AlignHCenter + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 15 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + RibbonBusyBar{ + Layout.topMargin: btn_layout.anchors.topMargin - title_layout.spacing + running: true + barWidth: control.width - btn_layout.anchors.topMargin * 4 + } + } + + Text { + id: log_text + anchors{ + left: parent.left + leftMargin: btn_layout.anchors.topMargin + bottom: parent.bottom + bottomMargin: btn_layout.anchors.topMargin + } + text: qsTr("Loading...") + font.family: Qt.platform.os === "osx" ? "PingFang SC" : "Microsoft YaHei UI" + font.pixelSize: 10 + color: RibbonTheme.isDarkMode ? "white" : "black" + renderType: RibbonTheme.nativeText ? Text.NativeRendering : Text.QtRendering + visible: text + Behavior on color { + ColorAnimation { + duration: 60 + easing.type: Easing.OutSine + } + } + } + + function showLog(log, others){ + log_text.text = log + } +}