隨着Qt的版本升級,其自帶的controls控件庫也不斷升級,目前已經到了2.3的版本。本文通過解讀Qt自帶的gallery例程,說明新版本controls控件庫的相關特性。其具體位置於:

因為相關的中文資料比較缺乏,所以這里的內容會詳細整理,某種意義上可以當作使用手冊來使用。
一、概況
運行界面為,應該說就是一個控件的展示集合

文件結構為:

二、細節
具體內容,按照名稱來划分
1、BusyIndicator主要用於忙等顯示,一般來說都是覆蓋整個界面,通過設置
visible來隱藏或者顯示;
界面 | 代碼 |
![]() |
BusyIndicator
{
id
:
busyindicator
visible
:
true
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
2、Button就是最簡單的按鈕控件,controls2提供的button帶有簡單的界面
界面 | 代碼 |
![]() |
ColumnLayout
{
spacing
:
20
anchors.horizontalCenter
:
parent
.horizontalCenter
Button
{
text
:
"First"
Layout.fillWidth
:
true
}
Button
{
id
:
button
text
:
"Second"
highlighted
:
true
Layout.fillWidth
:
true
}
Button
{
text
:
"Third"
enabled
:
false
Layout.fillWidth
:
true
}
}
|
3、CheckBox最簡單的選中/不選中控件,controls2提供的
CheckBox
帶有簡單的界面
界面 | 代碼 |
![]() |
Column
{
spacing
:
20
anchors.horizontalCenter
:
parent
.horizontalCenter
CheckBox
{
text
:
"First"
checked
:
true
}
CheckBox
{
text
:
"Second"
}
CheckBox
{
text
:
"Third"
checked
:
true
enabled
:
false
}
}
|
4、ComboBox是最簡單的下拉框控件,controls2提供的
ComboBox
包含可以修改正文內容和不可以修改內容2個
界面 | 代碼 |
![]() |
ComboBox
{
model
:
[
"First"
,
"Second"
,
"Third"
]
anchors.horizontalCenter
:
parent
.horizontalCenter
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ComboBox
{
editable
:
true
model
:
ListModel
{
id
:
model
ListElement
{
text
:
"Banana"
}
ListElement
{
text
:
"Apple"
}
ListElement
{
text
:
"Coconut"
}
}
onAccepted
:
{
if
(
find
(
editText
)
===
-1)
model
.append({text:
editText
})
}
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
5、DelayButton就是很有意思的按鈕控件,需要按下一段時間后才會觸發
界面 | 代碼 |
![]() |
DelayButton
{
text
:
"DelayButton"
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
6、Dial就是類似轉盤的控件,提供的是輸入的結果
界面 | 代碼 |
![]() |
Dial
{
value
:
0.5
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
7、Dialog就是窗體控件,controls2提供了集成的顯示,基本上還是提供了一個Dialog的基礎空間,然后在其上面畫各種樣式。注意dialog的model設置,就是是否模態顯示的意思;
standardButtons
:
Dialog
.Yes
|
Dialog
.No就是標准控件的意思
界面 | 代碼 |
![]() |
Button
{
text
:
"Message"
anchors.horizontalCenter
:
parent
.horizontalCenter
width
:
buttonWidth
onClicked
:
messageDialog
.open()
Dialog
{
id
:
messageDialog
x
:
(
parent
.width
-
width
)
/
2
y
:
(
parent
.height
-
height
)
/
2
title
:
"Message"
Label
{
text
:
"Lorem
ipsum
dolor
sit
amet..."
}
}
}
|
界面 | 代碼 |
![]() |
Button
{
id
:
button
text
:
"Confirmation"
anchors.horizontalCenter
:
parent
.horizontalCenter
width
:
buttonWidth
onClicked
:
confirmationDialog
.open()
Dialog
{
id
:
confirmationDialog
x
:
(
parent
.width
-
width
)
/
2
y
:
(
parent
.height
-
height
)
/
2
parent
:
Overlay.overlay
modal
:
true
title
:
"Confirmation"
standardButtons
:
Dialog
.Yes
|
Dialog
.No
Column
{
spacing
:
20
anchors.fill
:
parent
Label
{
text
:
"The
document
has
been
modified.\nDo
you
want
to
save
your
changes?"
}
CheckBox
{
text
:
"Do
not
ask
again"
anchors.right
:
parent
.right
}
}
}
}
|
這種模式用來顯示“關於”非常適合,使用的是Flickable
界面 | 代碼 |
![]() |
Button
{
text
:
"Content"
anchors.horizontalCenter
:
parent
.horizontalCenter
width
:
buttonWidth
onClicked
:
contentDialog
.open()
Dialog
{
id
:
contentDialog
x
:
(
parent
.width
-
width
)
/
2
y
:
(
parent
.height
-
height
)
/
2
width
:
Math
.min(
page
.width,
page
.height)
/
3
*
2
contentHeight
:
logo
.height
*
2
parent
:
Overlay.overlay
modal
:
true
title
:
"Content"
standardButtons
:
Dialog
.Close
Flickable
{
id
:
flickable
clip
:
true
anchors.fill
:
parent
contentHeight
:
column
.height
Column
{
id
:
column
spacing
:
20
width
:
parent
.width
Image
{
id
:
logo
width
:
parent
.width
/
2
anchors.horizontalCenter
:
parent
.horizontalCenter
fillMode
:
Image
.PreserveAspectFit
source
:
"../images/qt-logo.png"
}
Label
{
width
:
parent
.width
text
:
"Lorem
ipsum
dolor
sit
amet,
consectetur
adipiscing
elit.
Nunc
finibus
"
wrapMode
:
Label
.Wrap
}
}
ScrollIndicator.vertical
:
ScrollIndicator
{
parent
:
contentDialog
.contentItem
anchors.top
:
flickable
.top
anchors.bottom
:
flickable
.bottom
anchors.right
:
parent
.right
anchors.rightMargin
:
-
contentDialog
.rightPadding
+
1
}
}
}
}
|
界面 | 代碼 |
![]() |
Button
{
text
:
"Input"
anchors.horizontalCenter
:
parent
.horizontalCenter
width
:
buttonWidth
onClicked
:
inputDialog
.open()
Dialog
{
id
:
inputDialog
//直接設置在窗體中間
x
:
(
parent
.width
-
width
)
/
2
y
:
(
parent
.height
-
height
)
/
2
parent
:
Overlay.overlay
focus
:
true
modal
:
true
title
:
"Input"
standardButtons
:
Dialog
.Ok
|
Dialog
.Cancel
ColumnLayout
{
spacing
:
20
anchors.fill
:
parent
Label
{
elide
:
Label
.ElideRight
text
:
"Please
enter
the
credentials:"
Layout.fillWidth
:
true
}
TextField
{
focus
:
true
placeholderText
:
"Username"
Layout.fillWidth
:
true
}
TextField
{
placeholderText
:
"Password"
echoMode
:
TextField
.PasswordEchoOnEdit
Layout.fillWidth
:
true
}
}
}
}
|
8、Delegates就是委托按鈕控件,能夠將其他控件集成在一起顯示出來。它本身設計到涉及到設計模式,較為復雜,后面專題討論。
界面 | 代碼 |
![]() |
|
9、Frame就是將若干控件繼承在一起,有互斥屬性
界面 | 代碼 |
![]() |
Frame
{
anchors.horizontalCenter
:
parent
.horizontalCenter
Column
{
spacing
:
20
width
:
page
.itemWidth
RadioButton
{
text
:
"First"
checked
:
true
width
:
parent
.width
}
RadioButton
{
id
:
button
text
:
"Second"
width
:
parent
.width
}
RadioButton
{
text
:
"Third"
width
:
parent
.width
}
}
}
|
10、GroupBox和Frame非常類似
界面 | 代碼 |
![]() |
GroupBox
{
title
:
"Title"
anchors.horizontalCenter
:
parent
.horizontalCenter
Column
{
spacing
:
20
width
:
page
.itemWidth
RadioButton
{
text
:
"First"
checked
:
true
width
:
parent
.width
}
RadioButton
{
id
:
button
text
:
"Second"
width
:
parent
.width
}
RadioButton
{
text
:
"Third"
width
:
parent
.width
}
}
}
|
11、PageIndicator能夠簡單地將多幅界面包含在一起,我看用來做廣告是不錯。但是需要注意
PageIndicator只是顯示在最下面的那幾個小點點,如果需要顯示滑動界面,就必須要和其他控件配合使用
界面 | 代碼 |
![]() |
ScrollablePage
{
id
:
page
Column
{
spacing
:
40
width
:
parent
.width
Label
{
width
:
parent
.width
wrapMode
:
Label
.Wrap
horizontalAlignment
:
Qt
.AlignHCenter
text
:
"PageIndicator
is
used
to
indicate
the
currently
active
page
in
a
container
of
pages."
}
PageIndicator
{
count
:
5
currentIndex
:
2
anchors.horizontalCenter
:
parent
.horizontalCenter
}
}
}
|
12、ProgressBar就是運行狀態顯示界面。如果你對完成度能夠掌握的話,就可以使用ProgressBar替代busyindicator
界面 | 代碼 |
![]() |
ProgressBar
{
id
:
bar
value
:
0.5
anchors.horizontalCenter
:
parent
.horizontalCenter
}
ProgressBar
{
indeterminate
:
true
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
13、RadioButton就是單項選擇空間,一般需要包含在互斥的控件中去
界面 | 代碼 |
![]() |
Column
{
spacing
:
20
anchors.horizontalCenter
:
parent
.horizontalCenter
RadioButton
{
text
:
"First"
}
RadioButton
{
text
:
"Second"
checked
:
true
}
RadioButton
{
text
:
"Third"
enabled
:
false
}
}
|
14、RangeSlider不僅可以選擇結束,而且可以選擇開始
界面 | 代碼 |
![]() |
RangeSlider
{
id
:
slider
first.value
:
0.25
second.value
:
0.75
anchors.horizontalCenter
:
parent
.horizontalCenter
}
RangeSlider
{
orientation
:
Qt
.Vertical
first.value
:
0.25
second.value
:
0.75
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
15、
RangeSlider的小兄弟Slider
界面 | 代碼 |
![]() |
Slider
{
id
:
slider
value
:
0.5
anchors.horizontalCenter
:
parent
.horizontalCenter
}
Slider
{
orientation
:
Qt
.Vertical
value
:
0.5
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
16、SpinBox顯示加加減減的界面
界面 | 代碼 |
![]() |
SpinBox
{
id
:
box
value
:
50
anchors.horizontalCenter
:
parent
.horizontalCenter
editable
:
true
}
|
17、StackView是重要的,帶有生命周期的View界面
界面 | 代碼 |
![]() |
StackView
{
id
:
stackView
initialItem
:
page
Component
{
id
:
page
Pane
{
id
:
pane
width
:
parent
?
parent
.width
:
0
//
TODO:
fix
null
parent
on
destruction
Column
{
spacing
:
40
width
:
parent
.width
Label
{
width
:
parent
.width
wrapMode
:
Label
.Wrap
horizontalAlignment
:
Qt
.AlignHCenter
text
:
"StackView
provides
a
stack-based
navigation
model
which
can
be
used
with
a
set
of
interlinked
pages.
"
+
"Items
are
pushed
onto
the
stack
as
the
user
navigates
deeper
into
the
material,
and
popped
off
again
"
+
"when
he
chooses
to
go
back."
}
Button
{
id
:
button
text
:
"Push"
anchors.horizontalCenter
:
parent
.horizontalCenter
width
:
Math
.max(
button
.implicitWidth,
Math
.min(
button
.implicitWidth
*
2,
pane
.availableWidth
/
3))
onClicked
:
stackView
.push(
page
)
}
Button
{
text
:
"Pop"
enabled
:
stackView
.depth
>
1
width
:
Math
.max(
button
.implicitWidth,
Math
.min(
button
.implicitWidth
*
2,
pane
.availableWidth
/
3))
anchors.horizontalCenter
:
parent
.horizontalCenter
onClicked
:
stackView
.pop()
}
}
}
}
}
|
18、ScrollBar最重要的功能,就是可以通過拖動的方式將界面擴展,注意它的側邊欄
界面 | 代碼 |
![]() |
ScrollBar.vertical
:
ScrollBar
{
}
|
19、swipeview另一種可以擴展界面的View,注意這是和
PageIndicator
結合起來使用的
界面 | 代碼 |
![]() |
SwipeView
{
id
:
view
currentIndex
:
1
anchors.fill
:
parent
Repeater
{
model
:
3
Pane
{
width
:
view
.width
height
:
view
.height
Column
{
spacing
:
40
width
:
parent
.width
Label
{
width
:
parent
.width
wrapMode
:
Label
.Wrap
horizontalAlignment
:
Qt
.AlignHCenter
text
:
"SwipeView
provides
a
navigation
model
that
simplifies
horizontal
paged
scrolling.
"
+
"The
page
indicator
on
the
bottom
shows
which
is
the
presently
active
page."
}
Image
{
source
:
"../images/arrows.png"
anchors.horizontalCenter
:
parent
.horizontalCenter
}
}
}
}
}
PageIndicator
{
count
:
view
.count
currentIndex
:
view
.currentIndex
anchors.bottom
:
parent
.bottom
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
20、Switch是最簡單的開關控件
界面 | 代碼 |
![]() |
Switch
{
text
:
"First"
}
Switch
{
text
:
"Second"
checked
:
true
}
Switch
{
text
:
"Third"
enabled
:
false
}
|
21、TabBar就是tab構成的bar,和indicator類似,也是必須結合swipeview來使用
界面 | 代碼 |
![]() |
SwipeView
{
id
:
swipeView
anchors.fill
:
parent
currentIndex
:
tabBar
.currentIndex
Repeater
{
model
:
3
Pane
{
width
:
swipeView
.width
height
:
swipeView
.height
Column
{
spacing
:
40
width
:
parent
.width
Label
{
width
:
parent
.width
wrapMode
:
Label
.Wrap
horizontalAlignment
:
Qt
.AlignHCenter
text
:
"TabBar
is
a
bar
with
icons
or
text
which
allows
the
user"
+
"to
switch
between
different
subtasks,
views,
or
modes."
}
Image
{
source
:
"../images/arrows.png"
anchors.horizontalCenter
:
parent
.horizontalCenter
}
}
}
}
}
footer
:
TabBar
{
id
:
tabBar
currentIndex
:
swipeView
.currentIndex
TabButton
{
text
:
"First"
}
TabButton
{
text
:
"Second"
}
TabButton
{
text
:
"Third"
}
}
|
22、TextArea文字輸入區域
界面 | 代碼 |
![]() |
TextArea
{
width
:
Math
.max(
implicitWidth
,
Math
.min(
implicitWidth
*
3,
pane.availableWidth
/
3))
anchors.horizontalCenter
:
parent
.horizontalCenter
wrapMode
:
TextArea
.Wrap
text
:
"TextArea\n...\n...\n..."
}
|
23、TextField是TextArea的親弟兄
界面 | 代碼 |
![]() |
TextField
{
id
:
field
placeholderText
:
"TextField"
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
24
、ToolTip就是顯示ToolTip
界面 | 代碼 |
![]() |
Button
{
text
:
"Tip"
anchors.horizontalCenter
:
parent
.horizontalCenter
ToolTip.timeout
:
5000
ToolTip.visible
:
pressed
ToolTip.text
:
"This
is
a
tool
tip."
}
|
25、Tumbler就是從幾個簡單的數字中選擇一個
界面 | 代碼 |
![]() |
Tumbler
{
model
:
10
anchors.horizontalCenter
:
parent
.horizontalCenter
}
|
三、存在問題和下步計划
gallary例子較為全面地展現了controls2的使用,但是存在以下三個問題
一是按照名稱分類,略為混亂;二是輸入控件沒有值的獲取,不很完整;三是種類太多,難以把握全局。
下一步機會對整個gallary進行重構,這個一篇博客就太長了,我們放在下一篇(http://www.cnblogs.com/jsxyhelu/p/8452474.html)。
感謝閱讀至此,希望有所幫助!