自 QML 第一次發佈已通過去一年多的時間,但在企業應用領域,QML 一直沒有可以佔據必定地位。很大一部分緣由是,QML 缺乏一些在企業應用中亟需的組件,好比按鈕、菜單等。雖然移動領域,這些組件已經變得無關緊要,但在桌面系統中依然不可或缺。爲了解決這一問題,Qt 5.1 發佈了 Qt Quick 的一個全新模塊:Qt Quick Controls。顧名思義,這個模塊提供了大量相似 Qt Widgets 模塊那樣可重用的組件。本章咱們將介紹 Qt Quick Controls,你會發現這個模塊與 Qt 組件很是相似。git
爲了開發基於 Qt Quick Controls 的程序,咱們須要建立一個 Qt Quick Application 類型的應用程序,選擇組件集的時候注意選擇 Qt Quick Controls 便可:github
注意,Qt Creator 給出的是 Qt Quick Controls 1.0,而最新版本的 Qt 5.2 搭載的 Qt Quick Controls 是 1.1。1.1 比 1.0 新增長了一些組件,好比BusyIndicator
等。因此,若是你發現某個組件找不到,記得更新下 Qt Quick Controls 的版本。編輯器
Qt Quick Controls 1.1 提供了多種組件:ide
應用程序窗口 | |
用於描述應用程序的基本窗口屬性的組件 | |
ApplicationWindow | 對應QMainWindow ,提供頂層應用程序窗口 |
MenuBar | 對應QMenuBar ,提供窗口頂部橫向的菜單欄 |
StatusBar | 對應QStatusBar ,提供狀態欄 |
ToolBar | 對應QToolBar ,提供工具欄,能夠添加ToolButton 和其它組件 |
Action | 對應QAction ,提供可以綁定到導航和視圖的抽象的用戶界面動做 |
導航和視圖 | |
方便用戶在一個佈局中管理和顯示其它組件 | |
ScrollView | 對應QScrollView ,提供滾動視圖 |
SplitView | 對應QSplitter ,提供可拖動的分割視圖佈局 |
StackView | 對應QStackedWidget ,提供基於棧的層疊佈局 |
TabView | 對應QTabWidget ,提供帶有標籤的基於棧的層疊佈局 |
TableView | 對應QTableWidget ,提供帶有滾動條、樣式和表頭的表格 |
控件 | |
控件用於表現或接受用戶輸入 | |
BusyIndicator | 提供忙等示意組件 |
Button | 對應QPushButton ,提供按鈕組件 |
CheckBox | 對應QCheckBox ,提供複選框 |
ComboBox | 對應QComboBox ,提供下拉框 |
GroupBox | 對應QGroupBox ,提供帶有標題、邊框的容器 |
Label | 對應QLabel ,提供標籤組件 |
ProgressBar | 對應QProgressBar ,提供進度條組件 |
RadioButton | 對應QRadioButton ,提供單選按鈕 |
Slider | 對應QSlider ,提供滑動組件 |
SpinBox | 對應QSpinBox ,提供微調組件 |
Switch | 提供相似單選按鈕的開關組件 |
TextArea | 對應QTextEdit ,提供可以顯示多行文本的富文本編輯框 |
TextField | 對應QTextLine ,提供顯示單行文本的純文本編輯框 |
ToolButton | 對應QToolButton ,提供在工具欄上顯示的工具按鈕 |
ExclusiveGroup | 提供互斥 |
菜單 | |
用於構建菜單的組件 | |
Menu | 對應QMenu ,提供菜單、子菜單、彈出菜單等 |
MenuSeparator | 提供菜單分隔符 |
MenuItem | 提供添加到菜單欄或菜單的菜單項 |
StatusBar | 對應QStatusBar ,提供狀態欄 |
ToolBar | 對應QToolBar ,提供工具欄,能夠添加ToolButton 和其它組件 |
咱們嘗試實現一個編輯器。這是一個簡單的文本編輯器,具備新建、剪切、複製和粘貼等操做。程序運行出來效果以下:函數
整個程序都是在 IDE 幫咱們生成的 main.qml 中實現的。首先咱們須要添加import
語句:工具
1
2
|
import QtQuick 2.1
import QtQuick.Controls 1.1
|
注意咱們修改了 IDE 生成的默認語句。整個 QML 文檔的根元素是ApplicationWindow
:佈局
1
2
3
4
5
6
|
ApplicationWindow {
title: qsTr("Simple Editor")
width: 640
height: 480
...
}
|
ApplicationWindow
是應用程序的主窗口,相似QMainWindow
,提供了不少預約義的功能,好比菜單、工具欄等。代碼裏面的qsTr()
函數相似tr()
函數,用於之後的國際化。全部面向用戶的文本都應該使用這個函數。post
下面向ApplicationWindow
中添加控件:ui
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
menuBar: MenuBar {
Menu {
title: qsTr("&File")
MenuItem { action: newAction }
MenuItem { action: exitAction }
}
Menu {
title: qsTr("&Edit")
MenuItem { action: cutAction }
MenuItem { action: copyAction }
MenuItem { action: pasteAction }
MenuSeparator {}
MenuItem { action: selectAllAction }
}
}
toolBar: ToolBar {
Row {
anchors.fill: parent
ToolButton { action: newAction }
ToolButton { action: cutAction }
ToolButton { action: copyAction }
ToolButton { action: pasteAction }
}
}
TextArea {
id: textArea
anchors.fill: parent
}
|
首先看最後面的TextArea
,這是整個窗口的主要控件,相似於setCentralWidget()
函數調用。spa
menuBar
和toolBar
兩個屬性都是ApplicationWindow
提供的屬性。
menuBar
是MenuBar
類型的,因此咱們建立一個新的MenuBar
控件。MenuBar
具備層次結構,這是經過Menu
的嵌套實現的。每個菜單項都是用MenuItem
實現的;菜單項之間的分隔符則使用MenuSeparator
控件。這點與 QtWidgets 有所不一樣。
toolBar
是Item
類型的,不過一般都會使用ToolBar
控件。ToolBar
默認沒有提供佈局,所以咱們必須給它設置一個佈局。這裏咱們直接添加了一個Row
,做爲橫向工具欄的佈局。這個工具欄要橫向充滿父窗口,所以設置錨點爲anchors.fill: parent
。雖然咱們設置的是充滿整個父窗口,可是工具欄的行爲是,若是其中只有一個子元素(好比這裏的Row
),那麼工具欄的高度將被設置爲這個子元素的implicitHeight
屬性。這對結合佈局使用很是有用。事實上,這也是工具欄最經常使用的方法。工具欄中添加了四個按鈕,都是ToolButton
類型。
每個MenuItem
和ToolButton
都添加了一個action
屬性。下面是這部分代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
Action {
id: exitAction
text: qsTr("E&xit")
onTriggered: Qt.quit()
}
Action {
id: newAction
text: qsTr("New")
iconSource: "images/new.png"
onTriggered: {
textArea.text = "";
}
}
Action {
id: cutAction
text: qsTr("Cut")
iconSource: "images/cut.png"
onTriggered: textArea.cut()
}
Action {
id: copyAction
text: qsTr("Copy")
iconSource: "images/copy.png"
onTriggered: textArea.copy()
}
Action {
id: pasteAction
text: qsTr("Paste")
iconSource: "images/paste.png"
onTriggered: textArea.paste()
}
Action {
id: selectAllAction
text: qsTr("Select All")
onTriggered: textArea.selectAll()
}
|
Action
相似QAction
。這裏咱們仍是使用qsTr()
函數設置其顯示的文本。
使用iconSource
屬性能夠指定圖標。注意這裏的圖標只能是位於文件系統中的,不能加載資源文件中的圖標(固然,這並非絕對的。若是咱們將整個 QML 文檔放在資源文件中,那麼就能夠直接加載資源文件中的圖標。咱們會在後面的章節詳細介紹這種技術。)。當咱們直接相似「images/new.png」這種路徑時,注意 QML 是運行時解釋的,所以這個路徑是相對與 QML 文件的路徑。因此這裏的圖標須要放在與 main.qml 文件同目錄下的 images 目錄中。
onTriggered
屬性是一種信號處理函數,後面能夠添加 JavaScript 語句。若是是多條語句,可使用大括號,例如newAction
的onTriggered
。QML 組件能夠發出信號。與 C++ 不一樣的是,QML 組件的信號並不須要特別的鏈接語句,而是使用」on信號名字」的形式。好比,Action
有一個名爲triggered
的信號,則其信號處理函數即爲onTriggered
。事實上,這是最簡單的一種信號槽的實現。不過,這種實現的困難在於,同一個信號只能有一個固定名字的信號處理函數。不過,咱們也可使用 connect 鏈接語句。後面的章節中將詳細介紹這一點。
至此,咱們的編輯器便實現了。因爲所有使用了TextArea
提供的功能,因此代碼很簡單。不過,複雜的程序都是這些簡單的元素堆積而成,因此,咱們如今只是簡單介紹,具體的控件使用還要根據文檔仔細研究。