qml - 旋转框数字下的 QtQuick 按钮

标签 qml qtquick2 qspinbox

我想要一个旋转框,每个数字下面都有小按钮。根据选中的按钮,旋转框的步长将相应调整。例如,如果选择小数点左边的第一个按钮,则步长为 1;如果选择小数点右边的第一个按钮,则步长为 0.1。

我已经弄清楚如何获得我想要的所有行为,并将旋转框与适当的按钮组合在一起。

enter image description here

下一步是调整按钮的大小和位置,使它们直接在相应的数字位置下方对齐。在非常低的级别上,这将涉及获取字体详细信息,确定每个数字的大小和位置,然后相应地调整按钮的大小和位置。这是我可以在 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
                    }
                }
            }
        }
    }
}

最佳答案

您可以使用 FontMetrics 获取 QML 中的字体信息。如果您知道正在使用的字体中的字符大小都大致相同,则可以使用 averageCharacterWidth ,否则您可以使用 boundingRect TextMetrics的属性(property)与字符串的每个单独字符。这些类型的属性/功能有一些替代方案;检查文档。

您可能需要增加 fontpixelSizeletterSpacingSpinBox 中使用,因为默认情况下它们非常接近,这不会给单选按钮留下太多空间。

需要访问样式委托(delegate)实例的大小 ( incrementControl/decrementControl ) 才能找到文本右对齐的位置。这意味着您需要创建自己的 SpinBoxStyle以便您可以提供这些实例 ID 以便在其他地方访问它们。

但是,这些控件无法解决所有问题,而这个控件则非常具体。此时,创建您自己的 DecimalSpinBox 组件可能会更容易。然后,您可以完全控制字符和单选按钮的位置。一旦您创建了自己的样式(上面提到的先前方法),您就会失去 native 样式。

关于qml - 旋转框数字下的 QtQuick 按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31088616/

相关文章:

Qt QSpinBox : How to display uppercase hexadecimal number

qt - 在 .qml 文件中声明字符串

qt - 捕获QML绘图缓冲区,而不显示

qt - 如何在不缩放的情况下显示/遮盖图像的一部分-QtQuick/QML

c++ - QSpinBox 中的验证

c++ - QSpinBox with Unsigned Int for Hex Input

python - 从 Python 方法获取 QML 中的返回值

qt - Qml Text Item如何设置行间距?

gridview - 动态填充 GridView 时应用程序启动缓慢

ios - ApplicationWindow不遵守大小