QT Demo 之 window(2) Splash

QT Demo 之 window一章我們學習了在C++層的QQuickWindow的一些知識,這一章我們重點看一下源碼中的Splash.qml文件,該文件給我們演示瞭如何使用splash screen來顯示應用的啓動及界面。

關於應用的啓動界面,有一個最直觀也是比較常見的例子就是photoshop,下圖就是PS啓動時顯示的界面:

在這個例子裏也是先顯示一個Qt的Logo,然後再進入到主應用窗口中。

源碼結構

Splash.qml實現了一個自定義的window來完成Splash screen的功能,其中包括一個Image和Timer:

Window {
    id: splash
    color: "transparent"
    title: "Splash Window"
    modality: Qt.ApplicationModal
    flags: Qt.SplashScreen
    property int timeoutInterval: 2000
    signal timeout

    x: (Screen.width - splashImage.width) / 2
    y: (Screen.height - splashImage.height) / 2
    width: splashImage.width
    height: splashImage.height

    Image {...}
    Timer {...}

    Component.onCompleted: visible = true
}
其中color/modality/flags這三項的值非常重要,在幫助文檔中有如下的說明:

A splash screen can be created with the Qt.SplashScreen flag, and should be ApplicationModal to prevent interaction with the main window. If the splash window is also transparent, and showing a partially transparent image, then it will look like a shaped window.

即一個splash screen必須置Qt.SplashScreen標記,而且必須是模態窗口(即焦點必須停留在splash screen窗口上),這兩項是splash screen的基本屬性。爲了改善用戶體驗,一般會顯示一張圖片(如PhotoShop),而且支持漸變透明效果,所以要設置背景顏色爲transparent。

窗口位置和大小

因爲是splash screen,在顯示上一定要居中顯示。因此width和height分別等於顯示顯示的圖片width和height,但是x和y的座標要根據平鋪的大小進行計算:

    x: (Screen.width - splashImage.width) / 2
    y: (Screen.height - splashImage.height) / 2
    width: splashImage.width
    height: splashImage.height

這裏使用到了Screen對象,關於Screen有如下的說明:
The Screen attached object provides information about the Screen an Item or Window is displayed on.

Screen對象中定義了height、width以及其他一些和Screen相關的屬性,都是read-only。

顯示的圖片

顯示圖片使用的Image組件,代碼比較簡單:

    Image {
        id: splashImage
        source: "../shared/images/qt-logo.png"
        MouseArea {
            anchors.fill: parent
            onClicked: Qt.quit()
        }
    }
這裏單獨拿出來分析是因爲MouseArea的onClicked事件響應函數是:Qt.quit(),查詢文檔我們知道其目的是要退出應用。
但是在實際測試中,我們發現在Splash窗口出現時,單擊鼠標程序並沒有退出,而在調試窗口有下述的錯誤提示:
Signal QQmlEngine::quit() emitted, but no receivers connected to handle it.

這裏具體要怎麼做纔可以實現單擊的時候退出應用,目前還不清晰,留一個TODO

splash screen的隱藏

從設計的角度來講,Splash Screen的作用是在主窗口啓動前做一些初始化的操作,比如PhotoShop中的加載字體庫、畫筆等等,但是在這個示例程序中,是通過一個Timer來模擬的Splash Screen的退出事件的。

    Timer {
        interval: timeoutInterval; running: true; repeat: false
        onTriggered: {
            visible = false
            splash.timeout()
        }
    }

使用這個Timer要結合該組件的下面兩個元素:

    property int timeoutInterval: 2000
    signal timeout
其中timeoutInterval定義了Timer的觸發間隔,而timeout的類型是signal,這是一個新的類型。

在官方文檔中,關於如何添加自定義的signal是這麼說明的:
Signals can be added to custom QML types through the signal keyword.
The syntax for defining a new signal is:
signal <name>[([<type> <parameter name>[, ...]])]
A signal is emitted by invoking the signal as a method

在示例中就是定義了一個timeout的signal,並且在需要觸發的時候通過timeout()方法來觸發signal事件。

而signal事件響應函數是按照下述規範進行默認定義的:
Signal handlers for property change signal take the syntax form on<Property>Changed where <Property> is the name of the property, with the first letter capitalized.

那麼,Splash.qml的signal事件響應函數的名稱就是onTimeout,在window.qml中也是這麼使用的:

    property var splashWindow: Splash {
        onTimeout: controlWindow.visible = true
    }

因此,通過Timer以及signal的配合,完成了Splash Screen的退出和主窗口的顯示。

Window的顯示和隱藏

在Splash.qml的代碼最後有這麼的一行:

    Component.onCompleted: visible = true
那麼是不是Window默認都是隱藏不顯示的,需要手動使其顯示呢?答案是的

visible : bool
This property holds whether the window is visible or not.
This property controls the visibility of the window in the windowing system.
By default, the window is not visible, you must call setVisible(true), or show() or similar to make it visible.

因此就會出現Splash Screen的visible需要在Component.onCompleted事件響應函數中置爲true,而外面的主窗口需要在Splash Screen的onTimeout事件響應函數中置爲true。

總結

本節學到的知識點:

  1. 如何基於Window創建一個自定義的Splash Screen
  2. 如何獲取Screen的參數,並根據Screen保持Window的顯示居中
  3. 如何使用自定義的signal以及對應的signal響應函數
  4. Window的顯示和隱藏

這一章我們學習了Window中的一個特殊的例子Splash Screen,其運用場景也比較常見,通過使用Splash Screen在完成應用的啓動過程中能極大的改善用戶的體驗。
但是,在這一章的學習中,也留下了一個坑,就是如何在Splash Screen中直接退出程序。留待後續學習。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章