QT Demo 之 window(5) window.qml

在分析了main.cppSplashQt.quit()以及ScreenInfo之後,我們終於開始了正題:window.qml。

window.qml的主體結構

window.qml主體是一個QtObject,其中包含了4個子元素:palette、controlWindow、testWindow和splashWindow:

QtObject {
    property real defaultSpacing: 10
    property SystemPalette palette: SystemPalette { }

    property var controlWindow: Window {}

    property var testWindow: Window {}

    property var splashWindow: Splash {}
}

QtObject簡述

The QtObject type is a non-visual element which contains only the objectName property.
It can be useful to create a QtObject if you need an extremely lightweight type to enclose a set of custom properties.

從文檔中我們知道QtObject類型是一個超級簡單基本的類型,只包含一個objectName的屬性,但是可以通過風中一系列的自定義properties來擴展並完成需要的功能。這裏的代碼也是,在基本的QtObject下添加了4種擴展類型的properties和一個基本類型的property。

這裏面也提到了另外一個詞:lightweight,也就是在使用QtObject的時候主要不要做太複雜的操作和邏輯。這裏面有一個很典型的例子,可以參考Qt5.3.2/Examples/Qt-5.3/quick/demos/samegame/content/Settings.qml的代碼。

SystemPalette類型

The SystemPalette type provides access to the Qt application palettes. This provides information about the standard colors used for application windows, buttons and other features. These colors are grouped into three color groups: Active, Inactive, and Disabled. See the QPalette documentation for details about color groups and the properties provided by SystemPalette.
這裏創建了一個基於SystemPalette的對象palette,主要的作用是在下面的controlWindow中使用palette.window來賦值給color屬性:

        color: palette.window
這樣使用的目的(個人猜測)是:獲取背景窗口的顏色,來設置給當前窗口,以保持風格的一致性。

下面三組分別是palette.highlight、palette.dark和palette.text的運行效果對比:

看到這裏,我們大致瞭解到SystemPalette的一些屬性值是根據當前環境配置下的一些預定義的color數值。

controlWindow

controlWindow作爲該應用的默認窗口,在Splash Screen之後就會顯示controlWindow,具體界面見上面的運行效果中的任意一個。

先看一下controlWindow的程序代碼結構:

    property var controlWindow: Window {
        width: visibilityLabel.implicitWidth * 1.2
        height: col.implicitHeight + defaultSpacing * 2
        color: palette.window
        title: "Control Window"
        Column {}
    }

配合代碼以及運行效果,我們知道controlWindow就是一個Column的結構。其中寬度是按照中間的visibilityLabel的寬度乘以1.2;高度是按照整體的col的高度再加上一個間距值;顏色是上面提到的palette.window,在這裏具體的值是#f0f0f0;因爲我們這裏是一個window,所以需要設置標題,此處設置標題爲"Control Window"。

Column

之前的學習中有用到Column控件,此處不在展開,看一下Column中的具體元素:

        Column {
            id: col
            anchors.fill: parent
            anchors.margins: defaultSpacing
            spacing: defaultSpacing
            property real cellWidth: col.width / 3 - spacing
            Text { text: "Control the second window:" }
            Grid {}
            function visibilityToString(v) {}
            Text {}
            Rectangle {}
            ScreenInfo { }
        }
從代碼和運行效果圖對照來看,Column中包含以下幾行元素:

  • Text,顯示"Control the second window:"
  • Grid排列的兩個Button和四個CheckBox
  • 定義visibilityToString(v)函數
  • 又是Text,顯示第二個窗口的是否顯示的狀態
  • 通過Rectangle來模擬的一個黑色的分隔行
  • 調用ScreenInfo來顯示Screen的信息

注:在Column中還有一個成員函數:visibilityToString(),會在第二個Text中調用到。

Column中子元素只有Shared.Button和Shared.CheckBox是新出現的兩個空間,但是從命名上來看也不是屬於系統的基本控件,如Text、Rectangle等等。

Shared.Button控件

                Shared.Button {
                    id: showButton
                    width: col.cellWidth
                    text: testWindow.visible ? "Hide" : "Show"
                    onClicked: testWindow.visible = !testWindow.visible
                }
Shared.Button的使用代碼很簡單,主要包括常見的id、width,以及Button上顯示的文字和onClicked事件響應函數。

Shared.CheckBox控件

                Shared.CheckBox {
                    text: "Windowed"
                    height: showButton.height
                    width: col.cellWidth
                    Binding on checked { value: testWindow.visibility === Window.Windowed }
                    onClicked: testWindow.visibility = Window.Windowed
                }
相對於Shared.Button控件的使用方法上,多了一個Binding操作。其實在這裏是非常好理解的,使用C代碼可以表示如下:

if (testWindow.visibility == Window.Windowed)
	checked = true;
else
	checked = false;
這樣,就即滿足了單擊的時候,修改testWindow.visibility屬性,而且也完成,當testWindow.visibility屬性改變(單擊另外一個CheckBox)時,更新Shared.CheckBox的狀態。

注:具體關於Binding的使用,後面在專門的章節中學習。

通過Rectangle來模擬的一個黑色的分隔線

如何繪製一條分割線,下面是一種實現方法:

            Rectangle {
                id: horizontalRule
                color: "black"
                width: parent.width
                height: 1
            }

如何在QML中定義和使用函數

            function visibilityToString(v) {
                switch (v) {
                case Window.Windowed:
                    return "windowed";
                case Window.Minimized:
                    return "minimized";
                case Window.Maximized:
                    return "maximized";
                case Window.FullScreen:
                    return "fullscreen";
                case Window.AutomaticVisibility:
                    return "automatic";
                case Window.Hidden:
                    return "hidden";
                }
                return "unknown";
            }
官方文檔中沒有給出具體的定義,但是從上面的示例中可以看出,Qml中函數的定義和JS中基本相同,都包含以下幾點:

  • 弱數據類型,即參數和返回值都無需明確聲明類型
  • 通過function關鍵字進行函數聲明
  • 支持if/else、switch等分支處理方式

Window的visibility和visible屬性

在controlWindow中除了上面使用的控件,其主要功能就是通過點擊Button和CheckBox來改變testWindow的visibility和visible屬性。下面我們就看一下這兩個屬性的具體說明。

visibility : QWindow::Visibility
    The screen-occupation state of the window.
    Visibility is whether the window should appear in the windowing system as normal, minimized, maximized, fullscreen or hidden.
    When a window is not visible its visibility is Hidden, and setting visibility to Hidden is the same as setting visible to false.

visible : bool
    Whether the window is visible on the screen.
    Setting visible to false is the same as setting visibility to Hidden.

結合程序的實際運行效果,我們知道:

  • 設置visibility屬性爲Windowed/Minimized/Maximized/FullScreen/AutomaticVisibility中任意一個都會使得visible屬性爲true,即顯示Window
  • 直接修改visible屬性爲false,會使得visibility屬性變爲Hidden;但是當再次設置visible屬性爲true時,visibility屬性會自動設爲爲原來的值。即從Windowed隱藏後,再次顯示仍是Windowed。
  • 設置visibility屬性爲AutomaticVisibility時,會根據運行的平臺不同實際上設置爲Windowed/Minimized/Maximized/FullScreen四種中的具體一種,在PC平臺上,會設置爲Windowed。

testWindow 

testWindow的結構就比較簡單,運行界面中元素也很少,先看一下代碼的主結構:

    property var testWindow: Window {
        width: 320
        height: 240
        color: "#215400"
        title: "Test Window with color " + color
        flags: Qt.Window | Qt.WindowFullscreenButtonHint
        Rectangle {}
    }
testWindow中給出了具體的width和height;爲了顯示Rectangle,將整個Window的顏色設置爲"#215400";設置了窗口的標題爲"Test Window with color " + color;最後通過flags設置了窗口的Qt.Window和Qt.WindowFullscreenButtonHint屬性。

Window.flags

The window flags control the window's appearance in the windowing system, whether it's a dialog, popup, or a regular window, and whether it should have a title bar, etc.

通過給Window設定不同的flags,使得其表現出不同的顯示效果來。通過打印,我們得到controlWindow和testWindow的flags分別是:

  • 800F001:Qt::Window|Qt::WindowTitleHint|Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint
  • 80000001:Qt.Window | Qt.WindowFullscreenButtonHint

其中的Qt.Window不用多講,表示這是一個Window,其它的還有Qt::Widget、Qt::Dialog等等。而對於controlWindow還有Title欄、SystemMenu欄、最小/最大/關閉按鈕,而對於testWindow則是設置了Qt.WindowFullscreenButtonHint標記。而文檔中Qt.WindowFullscreenButtonHint標記的說明是“On Mac OS X adds a fullscreen button.”,那麼在Window系統上,testWindow則是相當於只設置了Qt.Window標記。

這裏需要注意的一點是,雖然對於testWindow沒有設置Qt::WindowTitleHint標記,也就是說沒有標題欄,但是爲什麼又有title屬性呢?其實title字段的值除了會顯示在標題欄,還會再底部的任務欄處顯示Window的標題,如下圖所示:

testWindow中的子元素

testWindow中的Rectangle中的代碼結構如下:

        Rectangle {
            anchors.fill: parent
            anchors.margins: defaultSpacing
            Text {}
            MouseArea {}
            Shared.Button {}
            Shared.Button {}
        }
其中涉及的Text、MouseArea以及剛纔學習到的Shared.Button都是已經掌握的知識,此處不再贅述,具體的參照運行效果。

總結

本章節學到的知識:

  1. Window的visible和visibility屬性及其改變後的效果
  2. SystemPalette系統調色板的使用
  3. 自定義控件Shared.Button和Shared.CheckBox的使用
  4. 如何在Qml中創建和使用函數
  5. Window中flags使用

這一章實際上就是重點演示了Window的visible和visibility屬性以及改變其值後的表現,並沒有講解和演示Window的各種屬性和設置等等。但是其中使用到的Shared.Button和Shared.CheckBox自定義控件卻是一個新知識,該章節中並沒有展開,後面有機會應該詳細學習一下。

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