QML Tumbler 基础用法:多滚轮选择与自定义外观

滚轮选择器大家应该不陌生:手机上调时间、选日期,就是一排排可以上下滚动的小窗格。QML 里做这种交互很简单,一个 Tumbler 组件就搞定。这篇从两个最基础的用法入手:一个把三个滚轮拼成时间选择器,另一个把滚轮项改成色块做颜色选择。

  • 基础示例 --- 时、分、AM/PM 三个滚轮组合成时间选择器,顺带解决只有两个选项的滚轮滚不动的问题
  • 颜色选择器 --- 自定义每个滚轮项的外观,做成色块,选中颜色实时预览

Demo 1:基础示例

三个滚轮分别选小时、分钟、上下午,下面一块时间牌实时显示当前选择。

演示代码

qml 复制代码
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

FadeInAnimation {
    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 15

        // ... 省略标题组件 TitleSeparator ...

        Row {
            Layout.alignment: Qt.AlignHCenter
            spacing: 20

            // 小时滚轮
            Column {
                spacing: 6
                Text {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "时"
                    font.pointSize: 11
                    color: "#666"
                }
                Tumbler {
                    id: hoursTumbler
                    model: 24
                    currentIndex: 12
                    height: 140
                }
            }

            // 分钟滚轮
            Column {
                spacing: 6
                Text {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "分"
                    font.pointSize: 11
                    color: "#666"
                }
                Tumbler {
                    id: minutesTumbler
                    model: 60
                    height: 140
                }
            }

            // 上下午滚轮
            Column {
                spacing: 6
                Text {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: "AM/PM"
                    font.pointSize: 11
                    color: "#666"
                }
                Tumbler {
                    id: amPmTumbler
                    model: ["AM", "PM"]
                    visibleItemCount: 2
                    height: 140
                }
            }
        }

        // 时间显示牌:凸显当前选择
        Rectangle {
            Layout.alignment: Qt.AlignHCenter
            Layout.topMargin: 10
            width: 280
            height: 56
            radius: 10
            color: "#EAF4FF"
            border.color: "#1296FF"
            border.width: 1

            Text {
                anchors.centerIn: parent
                text: "当前选择: " +
                      (hoursTumbler.currentIndex < 10 ? "0" : "") + hoursTumbler.currentIndex + ":" +
                      (minutesTumbler.currentIndex < 10 ? "0" : "") + minutesTumbler.currentIndex + " " +
                      amPmTumbler.model[amPmTumbler.currentIndex]
                font.pointSize: 16
                font.bold: true
                color: "#1296FF"
            }
        }

        Item { Layout.fillHeight: true }
    }
}

关键逻辑解析

Tumbler 最核心的就两个属性:model 决定滚轮里有哪些选项,currentIndex 是当前选中项的下标。model 给一个数字,就是 0 到 N-1 的整数;给字符串数组,滚轮里就是那些字符串。

三个滚轮各管各的,互不干扰。取时间的时候把三个 currentIndex 拼起来就行:

qml 复制代码
hoursTumbler.currentIndex + ":" + minutesTumbler.currentIndex + " " + amPmTumbler.model[amPmTumbler.currentIndex]

这里有个容易踩的坑:AM/PM 只有两个选项,但 Tumbler 默认的可视窗口是 5 项。选项比窗口还少的时候,滚轮会滚不动------怎么拖都弹回去。解决办法就是 visibleItemCount: 2,让可视窗口跟着选项数量走。

小时和分钟补零,用的是三元表达式:小于 10 就在前面拼一个 "0",这样显示出来是 "09:05" 而不是 "9:5"。时间牌是一块浅蓝底、蓝描边的圆角矩形,文字绑了三个滚轮的 currentIndex,随便滚哪个,时间都会跟着刷新。

Demo 2:颜色选择器

滚轮里每一项是一块颜色,滚到哪个颜色,右边的色块就变成哪个颜色,同时显示颜色名。

演示代码

qml 复制代码
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

FadeInAnimation {
    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 15

        // ... 省略标题组件 TitleSeparator ...

        Row {
            Layout.alignment: Qt.AlignHCenter
            spacing: 30

            Tumbler {
                id: colorTumbler
                width: 180
                height: 240
                model: ["Red", "Green", "Blue", "Yellow", "Cyan", "Magenta"]

                delegate: Rectangle {
                    width: colorTumbler.width
                    height: 40
                    color: modelData
                    border.color: "white"
                    border.width: 1

                    Text {
                        anchors.centerIn: parent
                        text: modelData
                        color: "white"
                        font.bold: true
                        font.pixelSize: 14
                    }
                }
            }

            // 右侧显示当前颜色
            Rectangle {
                width: 160
                height: 160
                anchors.verticalCenter: parent.verticalCenter
                radius: 12
                color: colorTumbler.model[colorTumbler.currentIndex]
                border.width: 2
                border.color: "#cccccc"

                Column {
                    anchors.centerIn: parent
                    spacing: 8

                    Text {
                        anchors.horizontalCenter: parent.horizontalCenter
                        text: "当前颜色"
                        color: "white"
                        font.pixelSize: 12
                        style: Text.Outline
                        styleColor: "#000000"
                    }

                    Text {
                        anchors.horizontalCenter: parent.horizontalCenter
                        text: colorTumbler.model[colorTumbler.currentIndex]
                        color: "white"
                        font.pixelSize: 18
                        font.bold: true
                        style: Text.Outline
                        styleColor: "#000000"
                    }
                }
            }
        }

        Item { Layout.fillHeight: true }
    }
}

关键逻辑解析

delegate 是滚轮项的"模板"。默认每个滚轮项就是一行文字,想要别的外观就重写它。这里把每一项换成一个 Rectangle 色块,modelData 就是当前项的数据(这里是颜色名),所以色块颜色直接绑 modelData 就行------滚轮里有几个颜色,就有几块对应颜色的色块。

选中联动是滚轮交互里最常用的套路:右侧色块的颜色取 colorTumbler.model[colorTumbler.currentIndex],选中项一变,颜色立刻跟着变。整个 demo 的关键就是这一行绑定。

文字用了描边(Text.Outline),这样不管色块是深色还是浅色,白色字都能看清。做颜色类选择器时这个小技巧挺实用。

对比

场景 用哪个 demo 关键点
多个滚轮拼一个值(时间、日期) 基础示例 多滚轮组合,读 currentIndex
选项只有两三个(AM/PM、开关) 基础示例 visibleItemCount 跟着选项数量调
滚轮项要有个性外观 颜色选择器 重写 delegate

运行验证

  1. 用 Qt Creator 打开 qml_tumbler/CMakeLists.txt
  2. Ctrl+R 运行;
  3. 左右滚三个时间滚轮,看时间牌变化;再到颜色选择器里滚色块。

扩展复用方向

  • 小时滚轮想改成 12 小时制,把 model: 24 换成 model: 12currentIndex 初始值改成 11 就行。
  • 颜色滚轮换个数据源,就是字体颜色、主题色的选择器,配合 Settings 还能记住上次的选择。
  • 时间牌如果想更醒目,把底色换成深色、文字用白色,就是一块电子表风格的时间显示。

已验证环境

相关推荐
Quz1 小时前
QML SpinBox 动画效果:缩放反馈与数字滚动
qt
小灰灰搞电子15 小时前
Qt 实现魔法导航菜单源码分享
开发语言·qt
Quz17 小时前
QML SpinBox 基础与步长控制:可编辑输入与自定义步长
qt
隐积18 小时前
Qt魔法之旅 · 全系列课程导航
qt
海清河晏11121 小时前
Qt 实战:信号与槽+事件系统
开发语言·c++·qt
郝学胜-神的一滴1 天前
Qt 高级编程 037:QSS按钮样式封神指南
开发语言·c++·qt·软件工程·用户界面
only-lucky1 天前
QML对话框控件
qt
郝学胜_神的一滴1 天前
Qt 高级编程 038:打造高颜值下拉菜单按钮
c++·qt
小灰灰搞电子1 天前
Qt 队列容器 QQueue 的详解与示例
开发语言·qt·qqueue