Qt Quick 簡單教程

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

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

    首先看一下《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 用來繪製一個填充矩形,能夠帶邊框,也能夠不帶,可使用純色填充,也可使用漸變色填充,甚至還能夠不填充而只提供邊框……async

    Rectangle 有不少屬性。ide

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

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

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

    Rectangle 還能夠繪製圓角矩形,你只要設置 radius 屬性就好了。

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  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 四個成分。你能夠這樣使用它們:

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. Text {  
  2.     color: "red"  
  3.   
  4.     // prints "1 0 0 1"  
  5.     Component.onCompleted: console.log(color.r, color.g, color.b, color.a)  
  6. }  

 

漸變色

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

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  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 屬性來實現。下面是示例:

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  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 來分組其它的可視圖元。如:

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Rectangle {  
  4.     width: 300;  
  5.     height: 200;  
  6.     Item {  
  7.         id: gradientGroup;  
  8.         Rectangle {  
  9.             x: 20;  
  10.             y: 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.   
  19.         Rectangle {  
  20.             x: 160;  
  21.             y: 20;  
  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.     }  
  31.   
  32.     Component.onCompleted: {  
  33.         console.log("visible children: " ,gradientGroup.visibleChildren.length);  
  34.         console.log("visible children: " ,gradientGroup.children.length);  
  35.         for(var i = 0; i < gradientGroup.children.length; i++){  
  36.             console.log("child " , i, " x = ", gradientGroup.children[i].x);  
  37.         }  
  38.     }  
  39. }  

 

    分組後能夠經過 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)四個邊的留白。看個圖就明白了:

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Rectangle {  
  4.     width: 300;  
  5.     height: 200;  
  6.   
  7.     Rectangle {  
  8.         id: rect1;  
  9.         anchors.left: parent.left;  
  10.         anchors.leftMargin: 20;  
  11.         anchors.top: parent.top;  
  12.         anchors.topMargin: 20;  
  13.         width: 120;  
  14.         height: 120;  
  15.         gradient: Gradient {  
  16.             GradientStop { position: 0.0; color: "#202020"; }  
  17.             GradientStop { position: 1.0; color: "#A0A0A0"; }  
  18.         }  
  19.     }  
  20.   
  21.     Rectangle {  
  22.         anchors.left: rect1.right;  
  23.         anchors.leftMargin: 20;  
  24.         anchors.top: rect1.top;  
  25.         width: 120;  
  26.         height: 120;  
  27.         rotation: 90;  
  28.         gradient: Gradient {  
  29.             GradientStop { position: 0.0; color: "#202020"; }  
  30.             GradientStop { position: 1.0; color: "#A0A0A0"; }  
  31.         }  
  32.     }  
  33. }  


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

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Rectangle {  
  4.     width: 300;  
  5.     height: 200;  
  6.   
  7.     Rectangle {  
  8.         color: "blue";  
  9.         anchors.fill: parent;  
  10.         border.width: 6;  
  11.         border.color: "#888888";  
  12.   
  13.         Rectangle {  
  14.             anchors.centerIn: parent;  
  15.             width: 120;  
  16.             height: 120;  
  17.             radius: 8;  
  18.             border.width: 2;  
  19.             border.color: "black";  
  20.             antialiasing: true;  
  21.             color: "red";  
  22.         }  
  23.     }  
  24. }  

 

Z 序 與 透明度

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

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

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Rectangle {  
  4.     width: 300;  
  5.     height: 200;  
  6.   
  7.     Rectangle {  
  8.         x: 20;  
  9.         y: 20;  
  10.         width: 150;  
  11.         height: 100;  
  12.         color: "#606080";  
  13.         z: 0.5;  
  14.     }  
  15.   
  16.     Rectangle {  
  17.         width: 100;  
  18.         height: 100;  
  19.         anchors.centerIn: parent;  
  20.         color: "#a0c080";  
  21.         z: 1;  
  22.         opacity: 0.6;  
  23.     }  
  24. }  


    除了視覺效果,有時咱們也須要安排圖元在場景中的 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 來顯示對應的數字。代碼以下:

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


    示例中用到了 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 屬性。

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Rectangle {  
  4.     width: 300;  
  5.     height: 200;  
  6.     Text {  
  7.         width: 150;  
  8.         height: 100;  
  9.         wrapMode: Text.WordWrap;  
  10.         font.bold: true;  
  11.         font.pixelSize: 24;  
  12.         font.underline: true;  
  13.         text: "Hello Blue Text";  
  14.         anchors.centerIn: parent;  
  15.         color: "blue";  
  16.     }  
  17. }  


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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Rectangle {  
  4.     width: 300;  
  5.     height: 200;  
  6.     Text {  
  7.         width: 150;  
  8.         height: 100;  
  9.         wrapMode: Text.WordWrap;  
  10.         font.bold: true;  
  11.         font.pixelSize: 24;  
  12.         font.underline: true;  
  13.         text: "Hello Blue <font color=\"blue\">Text</font>";  
  14.         anchors.centerIn: parent;  
  15.     }  
  16. }  


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

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


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

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

Button

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

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

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2. import QtQuick.Controls 1.1  
  3.   
  4. Rectangle {  
  5.     width: 300;  
  6.     height: 200;  
  7.     Button {  
  8.         anchors.centerIn: parent;  
  9.         text: "Quit";  
  10.         onClicked: Qt.quit();  
  11.     }  
  12. }  


    你能夠運行它看看效果。

    如今咱們再來看 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.   
  5. Rectangle {  
  6.     width: 300;  
  7.     height: 200;  
  8.     Button {  
  9.         text: "Quit";  
  10.         anchors.centerIn: parent;  
  11.         style: ButtonStyle {  
  12.             background: Rectangle {  
  13.                 implicitWidth: 70;  
  14.                 implicitHeight: 25;  
  15.                 border.width: control.pressed ? 2 : 1;  
  16.                 border.color: (control.hovered || control.pressed) ? "green" : "#888888";  
  17.             }  
  18.         }  
  19.     }  
  20. }  


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

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

    對於 ButtonStyle ,若是有多個按鈕同時用到,上面的方式就有點繁瑣了,能夠像下面這樣使用:

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2. import QtQuick.Controls 1.1  
  3. import QtQuick.Controls.Styles 1.1  
  4.   
  5. Rectangle {  
  6.     width: 300;  
  7.     height: 200;  
  8.   
  9.     Component{  
  10.         id: btnStyle;  
  11.         ButtonStyle {  
  12.             background: Rectangle {  
  13.                 implicitWidth: 70;  
  14.                 implicitHeight: 25;  
  15.                 color: "#DDDDDD";  
  16.                 border.width: control.pressed ? 2 : 1;  
  17.                 border.color: (control.hovered || control.pressed) ? "green" : "#888888";  
  18.             }  
  19.         }  
  20.     }  
  21.   
  22.     Button {  
  23.         id: openButton;  
  24.         text: "Open";  
  25.         anchors.left: parent.left;  
  26.         anchors.leftMargin: 10;  
  27.         anchors.bottom: parent.bottom;  
  28.         anchors.bottomMargin: 10;  
  29.         style: btnStyle;  
  30.     }  
  31.   
  32.     Button {  
  33.         text: "Quit";  
  34.         anchors.left: openButton.right;  
  35.         anchors.leftMargin: 6;  
  36.         anchors.bottom: openButton.bottom;  
  37.         style: btnStyle;  
  38.     }  
  39. }  


    此次咱們定義了一個組件,設置其 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(枚舉值)都會適時更新,你能夠根據它們判斷什麼時候結束你的加載等候提示界面。

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

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  1. import QtQuick 2.0  
  2.   
  3. Image {  
  4.     source: "images/yourimage.png"  
  5. }  


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

顯示網絡圖片

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

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


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

    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 屬性的真身了,看下面的代碼:

  1. 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 的使用,下面是顯示網絡圖片示例的代碼,再溫習下:

[javascript] view plain copy 在CODE上查看代碼片派生到個人代碼片
  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 應用了。恭喜你!

相關文章
相關標籤/搜索