有时候软件上的内容区域需要用户手动设置比例,SplitView 组件就是解决这个需求的。这篇文章用基础demo介绍概念,再给 Handle(拖拽手柄) 换个好看的样式。
SplitView 基础用法
拖中间的分隔条可以调整大小,支持切换横竖方向:

演示代码
qml
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts
FadeInAnimation {
id: root
property color mainColor: Theme.listColors[Theme.demo1]
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 50
color: Theme.demoStyle.frameBg
radius: 6
border.color: Theme.demoStyle.frameBorder
border.width: 1
RowLayout {
anchors.fill: parent
anchors.margins: 10
spacing: 10
Text {
text: "当前方向:"
font.pointSize: 10
color: Theme.demoStyle.frameText
}
Text {
text: splitView.orientation === Qt.Horizontal ? "水平" : "垂直"
font.pointSize: 10
color: root.mainColor
font.bold: true
}
Item { Layout.fillWidth: true }
CustomButton {
text: "切换方向"
onClicked: {
if (splitView.orientation === Qt.Horizontal) {
splitView.orientation = Qt.Vertical
} else {
splitView.orientation = Qt.Horizontal
}
}
}
}
}
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: Theme.demoStyle.frameBg
border.color: Theme.demoStyle.frameBorder
border.width: 1
radius: 6
SplitView {
id: splitView
anchors.fill: parent
anchors.margins: 10
orientation: Qt.Horizontal
handle: Rectangle {
implicitWidth: 6
implicitHeight: 6
color: root.mainColor
opacity: SplitHandle.pressed ? 1.0 : 0.7
}
// 面板1
CustomRect {
SplitView.minimumWidth: 80
SplitView.minimumHeight: 80
rectColor: Qt.color(root.mainColor).darker(1.0)
rectNum: "1"
}
// 面板2
CustomRect {
SplitView.minimumWidth: 80
SplitView.minimumHeight: 80
rectColor: Qt.color(root.mainColor).darker(1.2)
rectNum: "2"
}
}
}
}
}
说明: 这个 Demo 用到了工程里的几个共享组件,Theme 是颜色主题单例,CustomRect 是带编号的面板,CustomButton 是统一风格的按钮。它们只负责外观,不影响 SplitView 的核心逻辑,重点看 SplitView 本身。
SplitView的用法很简单,内部的子项自动排成一行或一列,拖动中间的分隔条时两侧面板跟着改变大小。想让面板保留最小空间,就在面板上写 SplitView.minimumWidth / SplitView.minimumHeight 附加属性。
切换方向的实现:
运行时修改 orientation 属性的值就可以了,水平变垂直 或者 垂直变水平,面板排列和分隔条方向都会自动跟着重排。
handle 指的是分隔条组件,是用户可以手动拖拽的部分。
自定义 Handle 样式
如图所示:

演示代码
qml
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
FadeInAnimation {
id: root
property color mainColor: Theme.listColors[Theme.demo2]
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 15
// ... 省略标题组件 TitleSeparator ...
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 45
color: Theme.demoStyle.frameBg
radius: 6
border.color: Theme.demoStyle.frameBorder
border.width: 1
RowLayout {
anchors.fill: parent
anchors.margins: 10
spacing: 10
Text {
text: "Handle样式:"
font.pointSize: 10
color: Theme.demoStyle.frameText
}
Text {
text: "渐变色 + 圆角"
font.pointSize: 10
color: root.mainColor
font.bold: true
}
Item { Layout.fillWidth: true }
}
}
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: Theme.demoStyle.frameBg
border.color: Theme.demoStyle.frameBorder
border.width: 1
radius: 6
SplitView {
id: splitView
anchors.fill: parent
anchors.margins: 10
orientation: Qt.Horizontal
handle: Rectangle {
id: handle
implicitWidth: 8
implicitHeight: 8
radius: 4
gradient: Gradient {
GradientStop { position: 0.0; color: root.mainColor }
GradientStop { position: 0.5; color: Qt.color(root.mainColor).darker(1.2) }
GradientStop { position: 1.0; color: root.mainColor }
}
opacity: splitView.resizing ? 1.0 : 0.3
// handle正中间
Rectangle {
width: splitView.orientation === Qt.Horizontal ? parent.width - 4 : 30
height: splitView.orientation === Qt.Horizontal ? 30 : parent.height - 4
radius: 4
color: Theme.demoStyle.handle
anchors.centerIn: parent
}
}
// 面板1
CustomRect {
SplitView.minimumWidth: 80
SplitView.minimumHeight: 80
rectColor: Qt.color(root.mainColor).darker(1.0)
rectNum: "1"
}
// 面板2
CustomRect {
SplitView.minimumWidth: 80
SplitView.minimumHeight: 80
rectColor: Qt.color(root.mainColor).darker(1.2)
rectNum: "2"
}
}
}
}
}
SplitView 的 handle 属性可以整个换掉,这里把分隔条重写成一条带圆角的渐变矩形。
opacity 属性绑的是 splitView.resizing,只有正在拖动分隔条时才完全显示,平时处于半透明状态,好处是不会抢占视觉焦点。
有个细节要注意:handle 里那个把手矩形的宽高是根据 splitView.orientation 算的,水平布局时横着摆、垂直布局时竖着摆,这样不管分隔条方向怎么变,把手都保持居中。改 handle 样式时保留这种方向判断,横竖切换才不会错位。
已验证环境:
- Qt 版本:Qt 6.8.2、Qt 6.11.1
- 操作系统:Windows 11
- GitHub:QML-Minimal-Demos/qml_splitview