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中直接退出程序。留待后续学习。。。

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