本文已参加【新人创作礼】活动,一起开启掘金创作之路。
📒博客首页:何名取 的个人主页 - 文章 - 掘金 (juejin.cn)
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❤️期待一起交流!
🙏作者水平很有限,如果发现错误,求告知,多谢!
🌺有问题可私信交流!!!
自定义组件TabWidget
前言
实现QML侧边导航栏的最简方法 - 掘金 (juejin.cn)前面一篇文章介绍了实现QML侧边导航栏的最简方法,采用的是更改TabBar和其组成部分TabButton位置和排列的方法。本节介绍的另外一种稍微复杂,但是移植性非常强的方法来实现QML侧边导航栏。
实现原理
视图切换功能
导航栏的按钮与视图存在一一对应的关系。点击第一个按钮,出现的是第一个界面,点击第二个按钮,出现的是第二个界面,不同的按钮对应着不同的界面。
在本节介绍的方法中,我使用的是将界面透明化的操作。原理就是将所有界面一块展现出来,层层堆叠,所有的界面的透明度都设置为0,它们都存在,只是从界面上无法看到。当第一个按钮被点击时,将第一个界面的透明度设置为1,于是第一个界面就显示了出来。同理,其他的按钮对应的界面也是这样,当按钮被点击,对应界面的透明度被设置为1,显示到视图上,而没有被对应到的界面的透明度依然为0,静静潜藏在人们的视觉之下。
function setOpacities() {
for (var i = 0; i < stack.children.length; ++i) {
stack.children[i].opacity = (i == current ? 1 : 0)
}
}
这个函数将会在每次按钮被点击时触发,进行遍历,实现上述隐藏其他界面,展示当前界面的操作。
导航栏垂直排列
导航栏垂直排列需要使用到Column类型来排列,Repeater类型来构造TabButton导航栏按钮。每个导航栏按钮的形状大小都是相同的,将Repeater类型的model属性设置为导航栏按钮的数量,delegate属性则是导航栏按钮的具体实现。以下是自定义组件TabWidget的完整代码。
import QtQuick 2.0
Item {
id: tabWidget
// Setting the default property to stack.children means any child items
// of the TabWidget are actually added to the 'stack' item's children.
// See the "Property Binding"
// documentation for details on default properties.
default property alias content: stack.children
property int current: 0
onCurrentChanged: setOpacities()
Component.onCompleted: setOpacities()
function setOpacities() {
for (var i = 0; i < stack.children.length; ++i) {
stack.children[i].opacity = (i == current ? 1 : 0)
}
}
Column {
id: side
Repeater {
model: stack.children.length
delegate: Rectangle {
height: tabWidget.height / stack.children.length; width: 80
color: tabWidget.current == index ? "LightBlue" : "SkyBlue"
Rectangle {
height: parent.height; width: 1
anchors { right: parent.right; rightMargin: 1 }
color: "SkyBlue"
}
Text {
horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter
anchors.fill: parent
text: stack.children[index].title
elide: Text.ElideRight
font.bold: tabWidget.current == index
}
MouseArea {
anchors.fill: parent
onClicked: tabWidget.current = index
}
}
}
}
Item {
id: stack
height: tabWidget.height
anchors.left: side.right; anchors.right: tabWidget.right
}
}
使用自定义组件
将自定义组件编写在另一个新的.qml文件中,保存后放在与main.qml文件同一路径下。在main.qml文件中引用。具体代码如下。
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
TabWidget {
id: tabs
anchors.fill: parent
Rectangle {
property string title: "Red"
anchors.fill: parent
Rectangle {
anchors.fill: parent;
color: "#ff7f7f"
Text {
width: parent.width - 20
anchors.centerIn: parent; horizontalAlignment: Qt.AlignHCenter
text: "Roses are red"
font.pixelSize: 20
wrapMode: Text.WordWrap
}
}
}
Rectangle {
property string title: "Green"
anchors.fill: parent
Rectangle {
anchors.fill: parent;
color: "#7fff7f"
Text {
width: parent.width - 20
anchors.centerIn: parent; horizontalAlignment: Qt.AlignHCenter
text: "Flower stems are green"
font.pixelSize: 20
wrapMode: Text.WordWrap
}
}
}
Rectangle {
property string title: "Blue"
anchors.fill: parent;
Rectangle {
anchors.fill: parent;
color: "#7f7fff"
Text {
width: parent.width - 20
anchors.centerIn: parent; horizontalAlignment: Qt.AlignHCenter
text: "Violets are blue"
font.pixelSize: 20
wrapMode: Text.WordWrap
}
}
}
}
}