開始使用QML編程(3)

Building a Text Editor

Declaring a TextArea

如果不包含一個可編輯的文字區域,我們的文本編輯器就不能稱之爲一個文本編輯器。QML的TextEdit元素允許我們聲明一個多行的可編輯的文字區域。TextEdit與Text元素不同,它不允許用戶直接編輯文本。

  1. TextEdit{  
  2.          id: textEditor  
  3.          anchors.fill:parent  
  4.          width:parent.width; height:parent.height  
  5.          color:"midnightblue"  
  6.          focus: true  
  7.   
  8.          wrapMode: TextEdit.Wrap  
  9.   
  10.          onCursorRectangleChanged: flickArea.ensureVisible(cursorRectangle)  
  11.      }  

編輯器設置了它的字體顏色,文本也是可以換行的。TextEdit區域位於一個flickable區域內,如果文本逛標位於可視區域外,文本可以滾動。ensureVisible()函數會檢查光標矩形是否在可視邊界外,相應地移動文本區域。QML的腳本使用JavaScript語法,正如我們之前提到的,Javascript 文件可以被導入到QML文件中使用。

 

  1. function ensureVisible(r){  
  2.          if (contentX >= r.x)  
  3.              contentX = r.x;  
  4.          else if (contentX+width <= r.x+r.width)  
  5.              contentX = r.x+r.width-width;  
  6.          if (contentY >= r.y)  
  7.              contentY = r.y;  
  8.          else if (contentY+height <= r.y+r.height)  
  9.              contentY = r.y+r.height-height;  
  10.      }  
 

Combining Components for the Text Editor

現在我們準備好使用QML來創建我們的文本編輯器的佈局。文本編輯器有兩個不見,我們創建的菜單欄和文本區域。QML允許我們重用組件,因此,在需要時通過導入和定製組件,使我們的代碼更加簡潔。我們的文本編輯器將窗口一分爲二:三分之一的屏幕留給菜單欄,另外的來顯示文本區域。菜單欄顯示在其他元素之前。

 

  1. Rectangle{  
  2.   
  3.          id: screen  
  4.          width: 1000; height: 1000  
  5.   
  6.          //the screen is partitioned into the MenuBar and TextArea. 1/3 of the screen is assigned to the MenuBar   
  7.          property int partition: height/3  
  8.   
  9.          MenuBar{  
  10.              id:menuBar  
  11.              height: partition  
  12.              width:parent.width  
  13.              z: 1  
  14.          }  
  15.   
  16.          TextArea{  
  17.              id:textArea  
  18.              anchors.bottom:parent.bottom  
  19.              y: partition  
  20.              color: "white"  
  21.              height: partition*2  
  22.              width:parent.width  
  23.          }  
  24.      }  
     

通過導入重用的組件,我們的TextEditor看起來更加簡單。之後我們可以定製主程序,而不必擔心已經定義好了行爲的那些屬性。通過這種方式,可以簡單的創建應用程序的佈局和UI組件。

menubar2

 

Decorating the Text Editor

Implementing a Drawer Interface

我們的文本編輯器看起來比較簡單,我們需要裝飾一下。使用QML,我們可以聲明轉換效果並讓我們的文本編輯器有動畫效果。我們的菜單欄佔用了三分之一的屏幕,如果我們讓它只有在我們需要它的時候才顯示出來多好。

 

我們可以添加一個抽屜(drawer)接口,當點擊時候它會縮短或擴展菜單欄。在我們的實現中,我們有一個響應鼠標點擊的小矩形。這個抽屜(drawer),和這個應用程序一樣,有兩個狀態,抽屜開(drawer is open)和抽屜關(drawer is closed)狀態。這個drawer item是一條有個很小的高度的矩形。一個嵌套的Image元素聲明瞭一個位於drawer中間的箭頭圖標。使用screen標識符,只要用戶點擊鼠標區域,這個drawer就爲整個程序指派一個狀態。

 

  1. Rectangle{  
  2.          id:drawer  
  3.          height:15  
  4.   
  5.          Image{  
  6.              id: arrowIcon  
  7.              source: "images/arrow.png"  
  8.              anchors.horizontalCenter: parent.horizontalCenter  
  9.          }  
  10.   
  11.          MouseArea{  
  12.              id: drawerMouseArea  
  13.              anchors.fill:parent  
  14.              onClicked:{  
  15.                  if (screen.state == "DRAWER_CLOSED"){  
  16.                      screen.state = "DRAWER_OPEN"  
  17.                  }  
  18.                  else if (screen.state == "DRAWER_OPEN"){  
  19.                      screen.state = "DRAWER_CLOSED"  
  20.                  }  
  21.              }  
  22.              ...  
  23.          }  
  24.      }  
 

狀態是一個簡單的配置集合,可以在State元素裏聲明。狀態列表可以羅列並綁定到states屬性。我們的程序中,這兩個狀態叫DRAWER_CLOSED和DRAWER_OPEN。item配置在PropertyChanges元素裏聲明。在DRAWER_OPEN狀態中,四個items會收到屬性改變。第一個目標,menuBar,會改變它的y屬性爲0。同樣地,當狀態是DRAWER_OPEN的時候,textArea會降到一個新位置。爲滿足當前的狀態,textArea、drawerdrawer的圖標都會響應屬性的改變。

 

  1. states:[  
  2.          State {  
  3.              name: "DRAWER_OPEN"  
  4.              PropertyChanges { target: menuBar; y: 0}  
  5.              PropertyChanges { target: textArea; y: partition + drawer.height}  
  6.              PropertyChanges { target: drawer; y: partition}  
  7.              PropertyChanges { target: arrowIcon; rotation: 180}  
  8.          },  
  9.          State {  
  10.              name: "DRAWER_CLOSED"  
  11.              PropertyChanges { target: menuBar; y:-height; }  
  12.              PropertyChanges { target: textArea; y: drawer.height; height: screen.height - drawer.height }  
  13.              PropertyChanges { target: drawer; y: 0 }  
  14.              PropertyChanges { target: arrowIcon; rotation: 0 }  
  15.          }  
  16.      ]  
 

平滑的過渡可以改變生硬的狀態變化。可以使用Transition元素來聲明狀態間的過渡。Transition可以綁定到item的transitions屬性。當狀態改變成DRAWER_OPEN或DRAWER_CLOSED的時候,我們的編輯器會有一個狀態過渡。過渡需要一個from和一個to狀態,這點很重要。不過對我們的過渡,我們可以使用通配符*來表示所有的狀態改變都需要應用過渡。

 

過渡中,我們可以指派動畫給屬性改變。menuBar的位置從y:0切換到y:-partition,我們可以使用NumberAnimation元素來動畫化這個過渡。我們聲明目標的屬性會使用一個特定的釋放(easing)曲線來動畫一段時間。釋放曲線控制了狀態過渡中的動畫等級和插入的行爲。我們選擇的釋放曲線是Easing.OutQuint,在靠近動畫結束的時候會減慢移動。請閱讀QML'的動畫文章。

  1. transitions: [  
  2.          Transition {  
  3.              to: "*"  
  4.              NumberAnimation { target: textArea; properties: "y, height"; duration: 100; easing.type:Easing.OutExpo }  
  5.              NumberAnimation { target: menuBar; properties: "y"; duration: 100; easing.type: Easing.OutExpo }  
  6.              NumberAnimation { target: drawer; properties: "y"; duration: 100; easing.type: Easing.OutExpo }  
  7.          }  
  8.      ]  

通過聲明一個Behavior元素是動畫化屬性改變的另一種方式。過渡僅適用在狀態改變時,Behavior可以爲一般的屬性改變設定一個動畫。在文本編輯器中,箭頭有一個NumberAnimation,當屬性改變時,動態改變它的rotation屬性。

  1. In TextEditor.qml:  
  2.   
  3.      Behavior{  
  4.          NumberAnimation{property: "rotation";easing.type: Easing.OutExpo }  
  5.      }  

有了狀態和動畫的知識,現在回到我們的組件,我們可以改善它們的外觀。在Button.qml中,當button點擊時,我們增加了color和scale屬性改變。顏色類型使用ColorAnimation動畫化,數字用NumberAnimation。下面顯示的on propertyName語法幫助我們確定單一的屬性目標。

 

  1. In Button.qml:  
  2.      ...  
  3.   
  4.      color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor  
  5.      Behavior on color { ColorAnimation{ duration: 55} }  
  6.   
  7.      scale: buttonMouseArea.pressed ? 1.1 : 1.00  
  8.      Behavior on scale { NumberAnimation{ duration: 55} }  
 

另外,我們可以通過添加諸如梯度漸變和不透明效果的顏色效果來增強我們的QML組件的外觀。聲明一個Gradient元素會覆蓋color 屬性。你可以使用GradientStop元素在梯度漸變中聲明一個顏色。梯度漸變使用0.0到1.0之間的scale來定位。

  1. In MenuBar.qml  
  2.      gradient: Gradient {  
  3.          GradientStop { position: 0.0; color: "#8C8F8C" }  
  4.          GradientStop { position: 0.17; color: "#6A6D6A" }  
  5.          GradientStop { position: 0.98;color: "#3F3F3F" }  
  6.          GradientStop { position: 1.0; color: "#0e1B20" }  
  7.      }  

菜單欄使用梯度漸變來顯示一個梯度漸變的模擬深度。第一個顏色在0.0,最後一個顏色在1.0.

轉自 http://www.cnblogs.com/smoozer/archive/2011/03/28/1997352.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章