QML定制TabBar
定制一个vertical TabBar,即垂直的TabBar。QT默认的TabBar都是水平的,且定制其Tab项的背景及字体等颜色都比较麻烦。我们今天来定制一个如下效果的垂直TabBar
:
1、默认TabBar
默认的TabBar实现如下,是由一个TabBar
加上一个StackLayout
组合实现,StackLayout
是一个栈布局,所谓栈布局简单来说就是同一时刻只能显示布局内的某一个栈元素,可以通过栈布局的currentIndex
来控制显示哪一个页签。TabButton
默认和TabBar
配合使用,作为TabBar
中的每一个独立的点击按钮存在。
TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("Home")
}
TabButton {
text: qsTr("Discover")
}
}
StackLayout {
width: parent.width
anchors.top: bar.bottom
anchors.bottom: parent.bottom
currentIndex: bar.currentIndex
Rectangle {
color: "red"
}
Rectangle {
color: "yellow"
}
}
上述的默认状态效果如下:
2、定制思路
采用一个ListView
来完成。其实查阅TabBar
的源码可以发现,源码本身也是使用一个ListView
来作为它的一个contentItem
项。
ListView
有一个orientation
属性用来指示列表是垂直的还是水平的,此处我们将其设置为ListView.Vertical
垂直的,ListView.Vertical
本身也是它的默认值,如果我们想使用水平的TabBar
就可以把这个值改为ListView.Horizontal
。
我们主要定制ListView
的代理delegate
,一般将它指定为一个ItemDelegate
即可。
ItemDelegate
有两个项可以定制一个是背景颜色background
,我们指定为一个Rectangle
,然后设置它的color
属性。另一个就是它的内容项contentItem
,此处我们使用一个Rectangle
,作为一个容器,可以设置背景颜色,同时在里面可以包含一个Text
,用来显示我们文本数据。另外,如果要想要改变鼠标的手势,或者增加一些点击事件的处理,可以在ItemDelegate
下增加一个MouseArea
,填充整个父对象(即ItemDelegate
)。
这里有一个关键问题就是,点击时如何做到tab的切换的?
ItemDelegate
的点击时触发clicked
信号,在onClicked
的槽函数中将ListView
的currentIndex
属性赋值为index
,其中index
是delegate
代理的默认属性,表示当前的索引值,代码如下
onClicked: control.currentIndex = index
3、整体架构
定制的TabBar
整体大致的代码架构如下所示:
delegate: ItemDelegate {
text: modelData
onClicked: control.currentIndex = index
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
}
contentItem: Rectangle {
anchors.fill: parent
Text {
anchors.fill: parent
text: tabDelegate.text
}
}
background: Rectangle {
color: tabBackgroundColor
}
}