Qt Quick 簡單教程(佈局開始)

https://blog.csdn.net/foruok/article/details/28859415

    上一篇《Qt Quick 之 Hello World 圖文詳解》我們已經分別在電腦和 Android 手機上運行了第一個 Qt Quick 示例—— HelloQtQuickApp ,這篇呢,我們就來介紹 Qt Quick 編程的一些基本概念,爲創建複雜的 Qt Quick 應用奠定基礎。

    版權所有 foruok ,如需轉載請註明來自博客 http://blog.csdn.net/foruok

    首先看一下《Qt Quick 之 Hello World 圖文詳解》中的 main.qml 文件:


    現在我們結合 main.qml 文件來講解。

import 語句

    main.qml 文件第一行代碼:import QtQuick 2.0 。這行代碼引入了 QtQuick 模塊, import 語句的作用與 C++ 中的 #include 類似,與 Java 中的 import 效果一樣。不再囉嗦了。

Qt Quick 基本元素

    Qt Quick 作爲 QML 的標準庫,提供了很多基本元素和控件來幫助我們構建 Qt Quick 應用。如果拿 C++ 來比擬, QML 就相當於 C++ 語言本身,而 Qt Quick 相當於 STL 。好吧,你可能覺得有點驢頭不對馬嘴,沒關係,有這麼點兒意思就成。

Rectangle

    main.qml 的第三行代碼,定義了一個 Rectangle 類型的對象作爲 QML 文檔的根對象。關於對象在 qml 文件中的描述,《Qt on Android:QML 語言基礎》一文中已經講解,這裏不再贅述。下面咱們看看 Rectangle 到底是什麼。

    Rectangle 用來繪製一個填充矩形,可以帶邊框,也可以不帶,可以使用純色填充,也可以使用漸變色填充,甚至還可以不填充而只提供邊框……

    Rectangle 有很多屬性。

    width 用來指定寬, height 用來指定高,我們已經見識過了。 

    color 屬性可以指定填充顏色,而 gradient 屬性則用來設置漸變色供填充使用,如果你同時指定了 color 和 gradient ,那麼 gradient 生效;如果你設置 color 屬性爲 transparent ,那麼就可以達到只繪製邊框不填充的效果。

    border.width 指定邊框的寬度, border.color 指定邊框顏色。

    Rectangle 還可以繪製圓角矩形,你只要設置 radius 屬性就行了。

    下面我們來看一個簡單的示例:

  1. Rectangle {
  2. width: 320;
  3. height: 480;
  4. color: "blue";
  5. border.color: "#808080";
  6. border.width: 2;
  7. radius: 12;
  8. }


    你可以修改 HelloQtQuickApp 的 main.qml 文件來查看效果,也可以建立一個新的工程。

    上面的 Rectangle 對象,我們

顏色

    關於顏色值, QML 中可以使用顏色名字,如 blue / red / green / transparent 等,也可以使用 "#RRGGBB" 或者 "#AARRGGBB" 來指定,還可以使用 Qt.rgba() / Qt.lighter() 等等方法來構造。詳情請參考 Qt SDK 中 "QML Basic Type: color" 頁面。

    color 類型有 r 、 g 、 b 、 a 四個屬性,分別表示一個顏色值的 red 、 green 、 blue 、 alpha 四個成分。你可以這樣使用它們:

  1. Text {
  2. color: "red"
  3. // prints "1 0 0 1"
  4. Component.onCompleted: console.log(color.r, color.g, color.b, color.a)
  5. }

漸變色

    QML 中漸變色的類型是 Gradient ,漸變色通過兩個或多個顏色值來指定, QML 會自動在你指定的顏色之間插值,進行無縫填充。Gradient 使用 GradientStop 來指定一個顏色值和它的位置(取值在 0.0 與 1.0 之間)。

    好吧,無碼不歡,快快看一個示例:

  1. Rectangle {
  2. width: 100;
  3. height: 100;
  4. gradient: Gradient {
  5. GradientStop { position: 0.0; color: "#202020"; }
  6. GradientStop { position: 0.33; color: "blue"; }
  7. GradientStop { position: 1.0; color: "#FFFFFF"; }
  8. }
  9. }

    Gradient 只能用來創建垂直方向的漸變,不過其它方向的,可以通過給 Rectangle 指定 rotation 屬性來實現。下面是示例:

  1. Rectangle {
  2. width: 100;
  3. height: 100;
  4. rotation: 90;
  5. gradient: Gradient {
  6. GradientStop { position: 0.0; color: "#202020"; }
  7. GradientStop { position: 1.0; color: "#A0A0A0"; }
  8. }
  9. }

    剛剛我們使用了 rotation 屬性,其實它來自 Rectangle 的父類 Item 。

Item

    Item 是 Qt Quick 中所有可視元素的基類,雖然它自己什麼也不繪製,但是它定義了繪製圖元所需要的大部分通用屬性,比如 x 、 y 、 width 、 height 、 錨定( anchoring )和按鍵處理。

    Item 的屬性特別多,除了前面提到的,還有 scale / smooth / anchors / antialiasing / enabled / visible / state / states / children 等等,詳情參考 Qt 幫助文檔。

    你可以使用 Item 來分組其它的可視圖元。如:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Item {
  6. id: gradientGroup;
  7. Rectangle {
  8. x: 20;
  9. y: 20;
  10. width: 120;
  11. height: 120;
  12. gradient: Gradient {
  13. GradientStop { position: 0.0; color: "#202020"; }
  14. GradientStop { position: 1.0; color: "#A0A0A0"; }
  15. }
  16. }
  17. Rectangle {
  18. x: 160;
  19. y: 20;
  20. width: 120;
  21. height: 120;
  22. rotation: 90;
  23. gradient: Gradient {
  24. GradientStop { position: 0.0; color: "#202020"; }
  25. GradientStop { position: 1.0; color: "#A0A0A0"; }
  26. }
  27. }
  28. }
  29. Component.onCompleted: {
  30. console.log("visible children: " ,gradientGroup.visibleChildren.length);
  31. console.log("visible children: " ,gradientGroup.children.length);
  32. for(var i = 0; i < gradientGroup.children.length; i++){
  33. console.log("child " , i, " x = ", gradientGroup.children[i].x);
  34. }
  35. }
  36. }

    分組後可以通過 Item 的 children 或 visibleChildren 屬性來訪問孩子元素,如上面的代碼所示。

    另外你可能注意到了, x 、 y 、 width 、 height 四個屬性結合起來,可以完成 Qt Quick 應用的界面佈局,不過這種採用絕對座標的方式來佈局,不太容易適應多種多樣的移動設備分辨率。而如果你看了《》,可能會注意到示例代碼中多次出現的 anchors 屬性,它 Item 的屬性,是 Qt Quick 引入的一種新的佈局方式。

使用 anchors 進行界面佈局

    anchors 提供了一種方式,讓你可以通過指定一個元素與其它元素的關係來確定元素在界面中的位置。

    你可以想象一下,每個 item 都有 7 條不可見的錨線:左(left)、水平中心(horizontalCenter)、上(top)、下(bottom)、右(right)、垂直中心(verticalCenter)、基線(baseline)。看下圖就明白了:


    在上圖中,沒有標註基線,基線是用於定位文本的,你可以想象一行文字端坐基線的情景。對於沒有文本的圖元,baseline 和 top 一致。

    使用 anchors 佈局時,除了對齊錨線,還可以在指定上(topMargin)、下(bottomMargin)、左(leftMargin)、右(rightMargin)四個邊的留白。看個圖就明白了:


    好了,基礎知識介紹完畢,可以看一些例子了。

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Rectangle {
  6. id: rect1;
  7. anchors.left: parent.left;
  8. anchors.leftMargin: 20;
  9. anchors.top: parent.top;
  10. anchors.topMargin: 20;
  11. width: 120;
  12. height: 120;
  13. gradient: Gradient {
  14. GradientStop { position: 0.0; color: "#202020"; }
  15. GradientStop { position: 1.0; color: "#A0A0A0"; }
  16. }
  17. }
  18. Rectangle {
  19. anchors.left: rect1.right;
  20. anchors.leftMargin: 20;
  21. anchors.top: rect1.top;
  22. width: 120;
  23. height: 120;
  24. rotation: 90;
  25. gradient: Gradient {
  26. GradientStop { position: 0.0; color: "#202020"; }
  27. GradientStop { position: 1.0; color: "#A0A0A0"; }
  28. }
  29. }
  30. }

    上面的代碼運行後與之前使用 Item 分組的示例代碼(絕對座標佈局)效果一樣。這裏的第二個矩形的左邊從第一個矩形的右邊開始、頂部向第一個矩形的頂部對齊。而對第一個矩形的引用,是通過的 id 屬性來完成的,請參看《Qt on Android:QML 語言基礎》。

    Item 的 anchors 屬性,除了上面介紹的,還有一些,如 centerIn 表示將一個 item 居中放置到另一個 item 內; fill 表示充滿某個 item ……更多請參考 Item 類的文檔。這裏再舉個使用 centerIn 和 fill 的示例:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Rectangle {
  6. color: "blue";
  7. anchors.fill: parent;
  8. border.width: 6;
  9. border.color: "#888888";
  10. Rectangle {
  11. anchors.centerIn: parent;
  12. width: 120;
  13. height: 120;
  14. radius: 8;
  15. border.width: 2;
  16. border.color: "black";
  17. antialiasing: true;
  18. color: "red";
  19. }
  20. }
  21. }

Z 序 與 透明度

    Item 除了 x 、 y 屬性,其實還有一個 z 屬性,用來指定圖元在場景中的 Z 序。 z 屬性的類型是 real ,數值越小,圖元就越墊底(遠離我們),數值越大,圖元就越靠近我們。

    Item 的屬性 opacity 可以指定一個圖元的透明度,取值在 0.0 到 1.0 之間。

    結合 Z 序和透明度,有時可以達到不錯的效果。下面是一個簡單的示例:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Rectangle {
  6. x: 20;
  7. y: 20;
  8. width: 150;
  9. height: 100;
  10. color: "#606080";
  11. z: 0.5;
  12. }
  13. Rectangle {
  14. width: 100;
  15. height: 100;
  16. anchors.centerIn: parent;
  17. color: "#a0c080";
  18. z: 1;
  19. opacity: 0.6;
  20. }
  21. }

    除了視覺效果,有時我們也需要安排圖元在場景中的 Z 序。比如一個圖片瀏覽器,可能在加載圖片時要顯示一個 loading 圖標,這個圖標要顯示在圖片之上,此時就可以設置 loading 圖元的 Z 序大於圖片元素的 Z 序。

按鍵處理

    前面提到 Item 可以處理案件,所有從 Item 繼承的元素都可以處理按鍵,比如 Rectangle ,比如 Button 。這點我們在《Qt on Android:QML 語言基礎》一文中介紹附加屬性時已經提到。

    Item 通過附加屬性 Keys 來處理按鍵。Keys 對象是 Qt Quick 提供的,專門供 Item 處理按鍵事件的對象。它定義了很多針對特定按鍵的信號,比如 onReturnPressed ,還定義了更爲普通的 onPressed 和 onReleased 信號,一般地,你可以使用這兩個信號來處理按鍵(請對照 Qt C++ 中的 keyPressEvent 和 keyReleaseEvent 來理解)。它們有一個名字是 event 的 KeyEvent 參數,包含了按鍵的詳細信息。如果一個按鍵被處理, event.accepted 應該被設置爲 true 以免它被繼續傳遞。

    這裏舉一個簡單的例子,檢測到 Escape 和 Back 鍵時退出應用,檢測到數字鍵,就通過 Text 來顯示對應的數字。代碼如下:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. color: "#c0c0c0";
  6. focus: true;
  7. Keys.enabled: true;
  8. Keys.onEscapePressed: Qt.quit();
  9. Keys.onBackPressed: Qt.quit();
  10. Keys.onPressed: {
  11. switch(event.key){
  12. case Qt.Key_0:
  13. case Qt.Key_1:
  14. case Qt.Key_2:
  15. case Qt.Key_3:
  16. case Qt.Key_4:
  17. case Qt.Key_5:
  18. case Qt.Key_6:
  19. case Qt.Key_7:
  20. case Qt.Key_8:
  21. case Qt.Key_9:
  22. keyView.text = event.key - Qt.Key_0;
  23. break;
  24. }
  25. }
  26. Text {
  27. id: keyView;
  28. font.bold: true;
  29. font.pixelSize: 24;
  30. text: qsTr("text");
  31. anchors.centerIn: parent;
  32. }
  33. }

    示例中用到了 onPressed / onEscapePressed / onBackPressed 三個附加信號處理器,其中 onPressed 信號的參數是 event ,包含了按鍵信息,程序中使用 switch 語句與 Qt 對象的枚舉值比較來過濾我們關注的按鍵。


    Item 還有很多的屬性,不再一一演示用法,請移步 Qt 幫助進一步瞭解。

    你肯定注意到了,上面的示例使用了 Text 這個對象,接下來我們就介紹它。

Text

    Text 元素可以顯示純文本或者富文本(使用 HTML 標記修飾的文本)。它有 font / text / color / elide / textFormat / wrapMode / horizontalAlignment / verticalAlignment 等等屬性,你可以通過這些屬性來決定 Text 元素如何顯示文本。

    當不指定 textFormat 屬性時, Text 元素默認使用 Text.AutoText ,它會自動檢測文本是純文本還是富文本,如果你明確知道要顯示的是富文本,可以顯式指定 textFormat 屬性。

    下面是一個簡單示例,顯示藍色的問題,在單詞分界處斷行:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Text {
  6. width: 150;
  7. height: 100;
  8. wrapMode: Text.WordWrap;
  9. font.bold: true;
  10. font.pixelSize: 24;
  11. font.underline: true;
  12. text: "Hello Blue Text";
  13. anchors.centerIn: parent;
  14. color: "blue";
  15. }
  16. }

    下面的例子僅僅把 "Text" 字樣以藍色顯示:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Text {
  6. width: 150;
  7. height: 100;
  8. wrapMode: Text.WordWrap;
  9. font.bold: true;
  10. font.pixelSize: 24;
  11. font.underline: true;
  12. text: "Hello Blue <font color=\"blue\">Text</font>";
  13. anchors.centerIn: parent;
  14. }
  15. }

    Text 元素的 style 屬性提供了幾種文字風格,Text.Outline 、 Text.Raised 、 Text.Sunken ,可以使文字有點兒特別的效果。而 styleColor 屬性可以和 style 配合使用(如果沒有指定 style ,則 styleColor 不生效),比如 style 爲 Text.Outline 時,styleColor 就是文字輪廓的顏色。看個簡單的示例:

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 300;
  4. height: 200;
  5. Text {
  6. id: normal;
  7. anchors.left: parent.left;
  8. anchors.leftMargin: 20;
  9. anchors.top: parent.top;
  10. anchors.topMargin: 20;
  11. font.pointSize: 24;
  12. text: "Normal Text";
  13. }
  14. Text {
  15. id: raised;
  16. anchors.left: normal.left;
  17. anchors.top: normal.bottom;
  18. anchors.topMargin: 4;
  19. font.pointSize: 24;
  20. text: "Raised Text";
  21. style: Text.Raised;
  22. styleColor: "#AAAAAA" ;
  23. }
  24. Text {
  25. id: outline;
  26. anchors.left: normal.left;
  27. anchors.top: raised.bottom;
  28. anchors.topMargin: 4;
  29. font.pointSize: 24;
  30. text: "Outline Text";
  31. style: Text.Outline;
  32. styleColor: "red";
  33. }
  34. Text {
  35. anchors.left: normal.left;
  36. anchors.top: outline.bottom;
  37. anchors.topMargin: 4;
  38. font.pointSize: 24;
  39. text: "Sunken Text";
  40. style: Text.Sunken;
  41. styleColor: "#A00000";
  42. }
  43. }

    這個示例除了用到 Text 元素,還使用 anchors 來完成界面佈局。

    Text 就介紹到這裏,下面看 Button 。

Button

    按鈕可能是 GUI 應用中最常用的控件了。 QML 中的 Button 和 QPushButton 類似,用戶點擊按鈕會觸發一個 clicked() 信號,在 QML 文檔中可以爲 clicked() 指定信號處理器,響應用戶操作。

    要使用 Button ,需要引入 import QtQuick.Controls 1.1 。

    先看一個簡單的示例,點擊按鈕,退出應用。代碼如下:

  1. import QtQuick 2.0
  2. import QtQuick.Controls 1.1
  3. Rectangle {
  4. width: 300;
  5. height: 200;
  6. Button {
  7. anchors.centerIn: parent;
  8. text: "Quit";
  9. onClicked: Qt.quit();
  10. }
  11. }

    你可以運行它看看效果。

    現在我們再來看 Button 都有哪些屬性。

    text 屬性指定按鈕文字,見過了。

    checkable 屬性設置 Button 是否可選。如果 Button 可選 checked 屬性則保存 Button 選中狀態。其實我一直沒用過這個屬性……

    iconName 屬性指定圖標的名字,如果平臺的圖標主題中存在該名字對應的資源, Button 就可以加載並顯示它。iconSource 則通過 URL 的方式來指定 icon 的位置。iconName 屬性的優先級高於 iconSource 。

    isDefault 屬性指定按鈕是否爲默認按鈕,如果是默認的,用戶按 Enter 鍵就會觸發按鈕的 clicked() 信號。

    pressed 屬性保存了按鈕的按下狀態。

    menu 屬性,允許你給按鈕設置一個菜單(此時按鈕可能會出現一個小小的下拉箭頭),用戶點擊按鈕時會彈出菜單。默認是 null 。

    action 屬性,允許設定按鈕的 action ,action 可以定義按鈕的 checked , text ,tooltip 等屬性。默認是 null 。

    activeFocusOnPress ,指定當用戶按下按鈕時是否獲取焦點,默認是 false 。

    style 屬性用來定製按鈕的風格,與它配套的有一個 ButtonStyle 類,允許你定製按鈕的背景。

    其實 Button 比較簡單好用,我不準備再囉嗦下去了,咱再看下 style 的使用就結束對 Button 的介紹。

ButtonStyle

    要使用 ButtonStyle 需要引入 QtQuick.Controls.Styles 1.1 。

    ButtonStyle 類有 background 、 control 、 label 三個屬性。我們通過重寫 background 來定製一個按鈕。 control 屬性指向應用 ButtonStyle 的按鈕對象,你可以用它訪問按鈕的各種狀態。 label 屬性代表按鈕的文本,如果你看它不順眼,也可以替換它。

    background 實際是一個 Component 對象, Component(組件) 的概念我們回頭講。這裏我們簡單的使用 Rectangle 來定製按鈕的背景。看下面的示例:

  1. import QtQuick 2.0
  2. import QtQuick.Controls 1.1
  3. import QtQuick.Controls.Styles 1.1
  4. Rectangle {
  5. width: 300;
  6. height: 200;
  7. Button {
  8. text: "Quit";
  9. anchors.centerIn: parent;
  10. style: ButtonStyle {
  11. background: Rectangle {
  12. implicitWidth: 70;
  13. implicitHeight: 25;
  14. border.width: control.pressed ? 2 : 1;
  15. border.color: (control.hovered || control.pressed) ? "green" : "#888888";
  16. }
  17. }
  18. }
  19. }

    我通過給 style 對象指定一個 ButtonStyle 對象來定製 Button 的風格。這個就地實現的 ButtonStyle 對象,重寫了 background 屬性,通過 Rectangle 對象來定義按鈕背景。我定義了背景的建議寬度和高度,根據按鈕的 pressed 屬性( control 是實際按鈕的引用 )來設置背景矩形的邊框粗細,而邊框顏色則隨着按鈕的 hovered 和 pressed 屬性來變化。

    最終的效果是這樣的:當鼠標懸停在按鈕上時,邊框顏色爲綠色;當鼠標按下時,邊框變粗且顏色爲綠色。

    對於 ButtonStyle ,如果有多個按鈕同時用到,上面的方式就有點繁瑣了,可以像下面這樣使用:

  1. import QtQuick 2.0
  2. import QtQuick.Controls 1.1
  3. import QtQuick.Controls.Styles 1.1
  4. Rectangle {
  5. width: 300;
  6. height: 200;
  7. Component{
  8. id: btnStyle;
  9. ButtonStyle {
  10. background: Rectangle {
  11. implicitWidth: 70;
  12. implicitHeight: 25;
  13. color: "#DDDDDD";
  14. border.width: control.pressed ? 2 : 1;
  15. border.color: (control.hovered || control.pressed) ? "green" : "#888888";
  16. }
  17. }
  18. }
  19. Button {
  20. id: openButton;
  21. text: "Open";
  22. anchors.left: parent.left;
  23. anchors.leftMargin: 10;
  24. anchors.bottom: parent.bottom;
  25. anchors.bottomMargin: 10;
  26. style: btnStyle;
  27. }
  28. Button {
  29. text: "Quit";
  30. anchors.left: openButton.right;
  31. anchors.leftMargin: 6;
  32. anchors.bottom: openButton.bottom;
  33. style: btnStyle;
  34. }
  35. }

    這次我們定義了一個組件,設置其 id 屬性的值爲 btnStyle ,在 Button 中設定 style 屬性時直接使用 btnStyle 。

    好啦, ButtonStyle 就介紹到這裏。下面該介紹 Image 了。

Image 

    Image 可以顯示一個圖片,只要是 Qt 支持的,比如 JPG 、 PNG 、 BMP 、 GIF 、 SVG 等都可以顯示。它只能顯示靜態圖片,對於 GIF 等格式,只會把第一幀顯示出來。如果你要顯示動畫,可以使用 AnimateSprite 或者 AnimateImage 。

    Image 的 width 和 height 屬性用來設定圖元的大小,如果你沒有設置它們,那麼 Image 會使用圖片本身的尺寸。如果你設置了 width 和 height ,那麼圖片就可能會拉伸來適應這個尺寸。此時 fillMode 屬性可以設置圖片的填充模式,它支持 Image.Stretch(拉伸) 、 Image.PreserveAspectFit(等比縮放) 、 Image.PreserveAspectCrop(等比縮放,最大化填充 Image ,必要時裁剪圖片) 、 Image.Tile(在水平和垂直兩個方向平鋪,就像貼瓷磚那樣) 、 Image.TileVertically(垂直平鋪) 、 Image.TileHorizontally(水平平鋪) 、 Image.Pad(保持圖片原樣不作變換) 等模式。

    Image 默認會阻塞式的加載圖片,如果要顯示的圖片很小,沒什麼問題,如果分辨率很高,麻煩就來了。此時你可以設置 asynchronous 屬性爲 true 來開啓異步加載模式,這種模式下 Image 使用一個線程來加載圖片,而你可以在界面上顯示一個等待圖標之類的小玩意兒來告訴用戶它需要等會兒。然後當 status(枚舉值) 的值爲 Image.Ready 時再隱藏加載等候界面。

    比較強悍的是, Image 支持從網絡加載圖片。它的 source 屬性類型是 url ,可以接受 Qt 支持的任意一種網絡協議,比如 http 、 ftp 等。而當 Image 識別到你提供的 source 是網絡資源時,會自動啓用異步加載模式。此時呢,Image 的 progress(取值範圍 0.0 至 1.0 ),status(枚舉值)都會適時更新,你可以根據它們判斷何時結束你的加載等候提示界面。

    算,先到這兒,看看怎麼用吧。下面是最簡的示例:

  1. import QtQuick 2.0
  2. Image {
  3. source: "images/yourimage.png"
  4. }

    source 替換爲一個實際存在的圖片路徑就可以看到效果。

顯示網絡圖片

    下面是一個稍微複雜點兒的示例,顯示網絡上的圖片,在下載和加載前顯示一個轉圈圈的 Loading 圖標,圖片加載成功後隱藏 Loading 圖標,如果加載出錯,則顯示一個簡單的錯誤消息。看代碼:

  1. import QtQuick 2.0
  2. import QtQuick.Controls 1.1
  3. Rectangle {
  4. width: 480;
  5. height: 320;
  6. color: "#121212";
  7. BusyIndicator {
  8. id: busy;
  9. running: true;
  10. anchors.centerIn: parent;
  11. z: 2;
  12. }
  13. Label {
  14. id: stateLabel;
  15. visible: false;
  16. anchors.centerIn: parent;
  17. z: 3;
  18. }
  19. Image {
  20. id: imageViewer;
  21. asynchronous: true;
  22. cache: false;
  23. anchors.fill: parent;
  24. fillMode: Image.PreserveAspectFit;
  25. onStatusChanged: {
  26. if (imageViewer.status === Image.Loading) {
  27. busy.running = true;
  28. stateLabel.visible = false;
  29. }
  30. else if(imageViewer.status === Image.Ready){
  31. busy.running = false;
  32. }
  33. else if(imageViewer.status === Image.Error){
  34. busy.running = false;
  35. stateLabel.visible = true;
  36. stateLabel.text = "ERROR";
  37. }
  38. }
  39. }
  40. Component.onCompleted: {
  41. imageViewer.source = "http://image.cuncunle.com/Images/EditorImages/2013/01/01/19/20130001194920468.JPG";
  42. }
  43. }

    圖片資源是我從網絡上搜索到的,僅僅用於演示程序,如有版權問題請提示我修改。

    Image 對象,設置了 asynchronous 屬性爲 true,不過對於網絡資源 Image 默認異步加載,這個屬性不起作用,只有你想異步加載本地資源時才需要設置它。 cache 屬性設置爲 false ,告訴 Image 不用緩存圖片。 fillMode 屬性我設置了等比縮放模式。

    onStatusChanged 是信號處理器,Image 的 status 屬性變化時會發射 statusChanged() 信號。之前在《QML 語言基礎》中介紹信號處理器時我們知道,信號處理器遵循 on{Signal} 語法,所以我們這裏的名字是 onStatusChanged 。在信號處理器的代碼塊中,我通過 Image 對象的 id 訪問它的 status 屬性,根據不同的狀態來更新界面。

    可能你會奇怪,在 Qt 幫助中, Image 類的參考手冊裏沒有明確提到 statusChanged 信號。其實呢,還有很多的信號, Qt 的文檔裏都沒有提到,嗚嗚,怎麼辦呢?教你個訣竅,去 SDK 頭文件中找,比如 Image 的頭文件是 Qt5.2.0\5.2.0\mingw48_32\include\QtQuick\5.2.0\QtQuick\private\qquickimage_p.h ,閱讀這個頭文件你會看到 QML 中的 Image 對應的 Qt C++ 中的 QQuickImage 類,而 QQuickImage 的父類是 QQuickImageBase ,QQuickImageBase 的類聲明在文件 Qt5.2.0\5.2.0\mingw48_32\include\QtQuick\5.2.0\QtQuick\private\qquickimagebase_p.h 中,找到這裏就找到 status 屬性的真身了,看下面的代碼:

Q_PROPERTY(Status status READ status NOTIFY statusChanged)
    Q_PROPERTY 宏用來定義 QObject 及其派生類的屬性,這樣定義的屬性可以在 QML 中訪問。上面的語句定義了只讀的 status 屬性並且指明當屬性變化時發送 statusChanged 信號。噢耶,K.O. !

    現在來看運行效果圖吧(我偷了個懶,都是直接修改 HelloQtQuickApp 的 main.qml 文件來看各種示例的效果)。下圖是加載過程:



    我設置了作爲 QML 文檔根元素的 Rectangle 對象的填充顏色爲 "#121212",所以背景是接近黑色的。下圖是圖片加載後的效果:


    怎麼樣,還不錯吧,等比縮放模式生效了。

    Qt Quick 是如此方便,以至於我不得不愛它!你看嘛,就不到 50 行代碼就可以實現一個基於網絡的圖片瀏覽器……

    說說這個示例中出現的新內容:BusyIndicator 。

BusyIndicator

    BusyIndicator 用來顯示一個等待圖元,在進行一些耗時操作時你可以使用它來緩解用戶的焦躁情緒。

    BusyIndicator 的 running 屬性是個布爾值, 爲 true 時顯示。 style 屬性允許你定製 BusyIndicator 。默認的效果就是前面圖示的那種,一個轉圈圈的動畫。

    至於 BusyIndicator 的使用,下面是顯示網絡圖片示例的代碼,再溫習下:

  1. BusyIndicator {
  2. id: busy;
  3. running: true;
  4. anchors.centerIn: parent;
  5. z: 2;
  6. }

    雖然 BusyIndicator 只有 running 和 style 兩個屬性,但它的祖先們有很多屬性,上面用到的 anchors 和 z ,都是從 Item 繼承來的屬性,可以直接使用。


    好嘛,總算到一階段,可以和簡單教程說再見了。

    版權所有 foruok ,如需轉載請註明來自博客 http://blog.csdn.net/foruok 。

    回顧一下前幾篇:

    如果你有耐心看到這裏,我想你肯定可以根據已經介紹的內容來完成一些比較複雜的 Qt Quick 應用了。恭喜你!

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