QML输入控件:Dial联动、音频均衡器的实现 (3)
目录
示例1:带数显的Dial
代码说明
适用场景
运行效果
示例2:多组Dial控件联动
代码说明
运行效果
示例3:音频均衡器界面
代码说明
运行效果
完整工程下载
在上篇中介绍了Dial控件与鼠标事件的应用,本文主要介绍Dial与其它控件的联动,以及音频均衡器界面的实现。
相关阅读:
QML输入控件: Dial基本用法与样式定制(1)-CSDN博客
QML输入控件: Dial与事件 (2)-CSDN博客
最终展示效果:
示例1:带数显的Dial
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("带数值显示的Dial")
Dial {
id: valueDisplayDial
width: 200
height: 200
from: 0
to: 100
Rectangle {
anchors.centerIn: parent
width: 60
height: 30
radius: 5
color: "#f0f0f0"
border.color: "#808080"
Text {
anchors.centerIn: parent
text: valueDisplayDial.value.toFixed(0)
font.bold: true
font.pixelSize: 14
}
}
}
}
这段 QML 代码实现了一个 带实时数值显示 的 Dial(旋钮)控件,数值会在旋钮中央以矩形框内的文本形式呈现。
代码说明
Dial控件:
- id: valueDisplayDial,宽高均为 200(未显式设置位置,默认左上角)。
- 数值范围:from: 0 到 to: 100(初始值未设置,默认 0)。
数值显示实现:
矩形背景(Rectangle):
- 居中于 Dial 内(anchors.centerIn: parent)。
- 尺寸 60x30,圆角 radius: 5。
- 浅灰色背景(#f0f0f0)和灰色边框(#808080)。
数值文本(Text):
- 显示 Dial 的当前值 valueDisplayDial.value.toFixed(0)(取整)。
- 样式:加粗(font.bold: true),字号 14px,居中显示。
适用场景
- 需要 直观显示当前值 的旋钮控件(如音量、亮度调节)。
运行效果
示例2:多组Dial控件联动
Row {
spacing: 20
anchors.centerIn: parent
Dial {
id: masterDial
width: 150
height: 150
from: 0
to: 100
value: 50
onValueChanged: {
slaveDial1.value = value / 2
slaveDial2.value = 100 - value
}
}
Dial {
id: slaveDial1
width: 120
height: 120
from: 0
to: 50
enabled: false
}
Dial {
id: slaveDial2
width: 120
height: 120
from: 0
to: 100
enabled: false
}
}
这段 QML 代码创建了一个 主从联动的 Dial(旋钮)组合。
代码说明
主从联动逻辑:
主 Dial(masterDial):
- 数值范围 0-100,初始值 50
- 值变化时(onValueChanged):
slaveDial1.value = value / 2 // 从 Dial1 值为一半
slaveDial2.value = 100 - value // 从 Dial2 值为反向
从 Dial(slaveDial1/slave2):
- 禁用交互(enabled: false),仅作为数值显示
范围限制:
- slaveDial1:0-50(主 Dial 值的一半范围)
- slaveDial2:0-100(与主 Dial 反向)
运行效果
示例3:音频均衡器界面
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("音频均衡器界面")
color: "#1a1a1a"
Grid {
columns: 5
spacing: 20
anchors.centerIn: parent
// 使用对象数组存储数值
property var bandNames: ["60Hz", "150Hz", "400Hz", "1kHz", "2.4kHz"]
property var bandValues: ([-12, -12, -12, -12, -12].map(v => ({ value: v }))) // 补全闭合括号
Repeater {
model: 5
Column {
id: bandColumn
spacing: 8
width: 90
Dial {
id: dial
width: 80
height: 80
from: -12
to: 12
value: 0
snapMode: Dial.SnapAlways
stepSize: 1.0
readonly property real innerRadius: bg.width/2
- bg.border.width
- handleItem.width/2
background: Rectangle {
id: bg // 给背景命名
radius: width / 2
color: "#333333"
border.color: "#555555"
border.width: 2
}
handle: Rectangle {
id: handleItem
width: 16
height: 16
radius: width / 2
antialiasing: true
color: "lime"
transform: [
Translate {
x: bg.width/2 - handleItem.width/2
y: bg.height/2 - handleItem.height/2 - dial.innerRadius
},
Rotation {
angle: dial.angle
origin.x: bg.width/2
origin.y: bg.height/2
}
]
}
// 强制触发数组更新
onValueChanged: {
let temp = [...bandColumn.parent.bandValues]
temp[index].value = Number(value.toFixed(1))
bandColumn.parent.bandValues = temp
}
}
Text {
text: bandColumn.parent.bandNames[index]
color: "white"
font.pixelSize: 14
anchors.horizontalCenter: parent.horizontalCenter
}
// 直接绑定dial.value
Text {
text: Number(dial.value.toFixed(1)) + " dB"
color: "lime"
font.pixelSize: 14
font.bold: true
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
}
这段代码实现了一个带五个调节旋钮的音频均衡器界面,每个旋钮都能在圆圈范围内转动并实时显示数值.
代码说明
界面架构:
- 创建深色背景窗口(#1a1a1a),使用5列网格布局(Grid)居中显示5个频段控件,列间距20像素
- 每个频段模块采用垂直布局(Column),包含旋钮+频率标签+数值显示
数据管理:
- 频段名称通过bandNames数组存储(60Hz~2.4kHz)
- 数值存储采用对象数组bandValues,初始值均为-12,通过.map生成响应式对象
- 数值更新时强制创建数组副本触发数据绑定(onValueChanged)
旋钮控件:
- 通过几何计算(innerRadius)约束手柄移动范围,结合平移+旋转变换实现定位逻辑
动态交互:
- 手柄位置实时绑定旋钮角度(dial.angle),极坐标公式计算偏移量
- 数值变化时同步更新显示文本,保留1位小数并附加dB单位
- 频段名称与数值采用双行文字显示,白色频率标签+绿色数值的对比设计
示例已做出如下优化:
- 解决括号不匹配导致的语法错误,规范箭头函数写法
- 将innerRadius定义为Dial的只读属性,避免手柄组件内重复计算
- 采用对象封装数值({ value: v })确保响应式更新有效性
- 文本控件直接绑定旋钮实时值(dial.value),保证显示即时性
运行效果
完整工程下载
https://gitcode.com/u011186532/qml_demo/tree/main/qml_dial