我想在每个数字下都有一个带有小按钮的旋转框。根据选中的按钮,微调框的步长将相应调整。例如,如果选择小数点左侧的第一个按钮,则步长为 1,如果选择小数点右侧的第一个按钮,则步长为 0.1。
我已经弄清楚如何获得我想要的所有行为,并将旋转框与适当的按钮结合起来。
下一步是调整按钮的大小和位置,使它们直接排列在相应的数字位置下方。在非常低的级别上,这将涉及获取字体详细信息,确定每个数字的大小和位置,然后相应地调整按钮的大小和位置。这是我可以在 qml 中实现的吗?
这是上述按钮的 qml:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
Item {
id: root
property int decimalsLeft: 2
property int decimalsRight: 3
property alias maximumValue: spinBox.maximumValue
property alias minimumValue: spinBox.minimumValue
property alias value: spinBox.value
width: layout.width
height: layout.height
ColumnLayout {
id: layout
SpinBox {
id: spinBox
Layout.fillWidth: true
width: parent.width
decimals: root.decimalsRight
horizontalAlignment: Qt.AlignRight
maximumValue: 1e3
minimumValue: -1e3
}
// Make row of buttons under number to select
// step size
ExclusiveGroup {id: decimalSelector}
RowLayout{
Repeater {
id: rdButtons
RadioButton {
exclusiveGroup: decimalSelector
onCheckedChanged: {
if(!checked) {
return
}
var relIndex = decimalsLeft-index-1
if(relIndex == -1) {// decimal location so don't do anything
return
}
if(relIndex < 0) {
relIndex += 1
}
spinBox.stepSize = Math.pow(10, relIndex)
}
}
onModelChanged: {
for(var i=0; i<rdButtons.count; i++) {
rdButtons.itemAt(i).enabled = true
}
// disable selector associated with the decimal point
if(rdButtons.count > decimalsLeft) {
rdButtons.itemAt(decimalsLeft).enabled = false
}
// now find which selector matches our current step size
var log = Math.round(Math.log(spinBox.stepSize) / Math.LN10)
var idx = -1
if(log >= 0) {
idx = decimalsLeft-log-1
}
else {
idx = decimalsLeft-log
}
// an finally apply the selection
if(rdButtons.count == 0) {
return
}
else if(idx < 0) {
rdButtons.itemAt(0).checked = true
}
else if(idx >= rdButtons.count) {
if(idx == decimalsLeft+1) {
rdButtons.itemAt(rdButtons.count-2).checked = true
}
else {
rdButtons.itemAt(rdButtons.count-1).checked = true
}
}
else {
rdButtons.itemAt(idx).checked = true
}
}
model: decimalsLeft + decimalsRight + 1
Component.onCompleted: {
if(decimalsLeft < rdButtons.count) {
rdButtons.itemAt(decimalsLeft).enabled = false
}
if(decimalsLeft > 0) {
rdButtons.itemAt(decimalsLeft-1).checked = true
}
}
}
}
}
}