2

各数字の下に小さなボタンがあるスピン ボックスが必要です。チェックされているボタンに応じて、スピンボックスのステップ サイズが調整されます。たとえば、小数点の左側の最初のボタンが選択されている場合、ステップ サイズは 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
                    }
                }
            }
        }
    }
}
4

1 に答える 1

2

FontMetricsで QML のフォント情報を取得できます。使用しているフォントの文字がほぼ同じサイズであることがわかっている場合は、averageCharacterWidthを使用できます。それ以外の場合は、文字列の個々の文字でTextMetricsのboundingRectプロパティを使用できます。これらの型のプロパティ/関数に関して、いくつかの代替手段があります。ドキュメントを確認してください。

で使用されているフォントpixelSizeのとletterSpacingを大きくする必要があるでしょう。これは、デフォルトでこれらが非常に接近しているため、ラジオ ボタンに十分なスペースが残されていないためです。SpinBox

テキストが右揃えされる位置を見つけるには、スタイル デリゲート インスタンス ( incrementControl / decrementControl ) のサイズへのアクセスが必要になります。つまり、独自のSpinBoxStyleを作成して、これらのインスタンス ID を指定して別の場所からアクセスできるようにする必要があります。

ただし、コントロールはすべての問題に対応できるわけではなく、これは非常に特殊です。この時点で、独自のDecimalSpinBoxコンポーネントを作成する方が簡単かもしれません。その後、文字とラジオ ボタンの配置場所を完全に制御できます。独自のスタイル (上記の前のアプローチ) を作成するとすぐに、ネイティブ スタイルは失われます。

于 2015-06-27T14:45:39.727 に答える