如何使用QML的‘Shape’绘制复杂自定义Tab Bar控件?
用QML Shape实现精美Tab Bar控件
这类Tab Bar的核心是自定义绘制选中项的弧形背景,利用QML的Shape结合Path系列元素可以轻松实现。下面是完整的实现方案和代码示例:
核心思路
- 用
Row作为Tab项的容器,保证横向排列 - 每个Tab项包含
Shape(绘制选中态背景)、Text(显示标签)和MouseArea(处理点击) - 通过
Path+PathArc绘制带圆角的选中背景轮廓,替代默认的矩形样式
完整代码示例
import QtQuick 2.15 import QtQuick.Shapes 1.15 Item { width: 400 height: 60 // 当前选中Tab的索引,可外部绑定 property int currentIndex: 0 Row { anchors.fill: parent spacing: 0 // 复用的Tab项组件 Component { id: tabItem Item { property string label: "" property bool selected: false width: parent.width / 3 height: parent.height // 选中态背景Shape Shape { visible: selected anchors.fill: parent fillColor: "#4CAF50" strokeColor: "#2E7D32" strokeWidth: 1 Path { startX: 0; startY: 0 // 顶部横线到右上角 PathLine { x: parent.width; y: 0 } // 右下角圆角弧 PathArc { x: parent.width; y: parent.height - 8 radiusX: 8; radiusY: 8 sweepDirection: PathArc.Clockwise } // 底部横线到左下角 PathLine { x: 0; y: parent.height - 8 } // 左上角圆角弧,闭合路径 PathArc { x: 0; y: 0 radiusX: 8; radiusY: 8 sweepDirection: PathArc.Clockwise } } } Text { text: label anchors.centerIn: parent color: selected ? "#ffffff" : "#333333" font.pixelSize: 16 font.weight: selected ? Font.Medium : Font.Normal } MouseArea { anchors.fill: parent onClicked: parent.parent.parent.currentIndex = index } } } // 批量生成Tab项 Repeater { model: ["首页", "发现", "我的"] delegate: tabItem { label: modelData selected: currentIndex === index } } } }
关键细节说明
- PathArc参数:
radiusX/Y控制圆角大小,sweepDirection决定圆弧的绘制方向,调整这两个参数可以匹配你需要的弧度样式 - 状态切换:通过
currentIndex绑定每个Tab的selected属性,自动切换Shape的可见性和文字样式 - 扩展性:如果需要渐变背景,将
fillColor替换为Gradient即可:fillColor: Gradient { GradientStop { position: 0; color: "#66BB6A" } GradientStop { position: 1; color: "#43A047" } } - 动画优化:可以给Shape添加淡入动画,提升交互体验:
Shape { // ... NumberAnimation on opacity { from: 0; to: 1 duration: 200 running: selected } }
内容的提问来源于stack exchange,提问作者Leaf Cpp
相关产品推荐
相关产品推荐

