2015-06-27 4 views
2

Я хочу, чтобы у каждого номера была прямая коробка с маленькими кнопками. В зависимости от того, какая кнопка отмечена, размер шага отпитки будет регулироваться в соответствии. Например, если выбрана первая кнопка слева от десятичной дроби, размер шага равен 1, и если выбрана первая кнопка справа от десятичной дроби, размер шага равен 0,1.Кнопки QtQuick под номерами спинбонов

Я выяснил, как получить все поведение, которое я хочу, и я объединил спин-бокс с соответствующими кнопками.

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 
        } 
       } 
      } 
     } 
    } 
} 

ответ

2

Вы можете получить информацию о шрифтах в QML с FontMetrics. Если вы знаете, что символы шрифта, который вы используете, имеют одинаковый размер, вы можете использовать averageCharacterWidth, иначе вы можете использовать свойство boundingRectTextMetrics с каждым отдельным символом строки. Существует несколько альтернатив с точки зрения свойств/функций в этих типах; проверьте документацию.

Вы, возможно, потребуется увеличить pixelSize и letterSpacing из font, используемого в SpinBox, потому что они довольно близко друг к другу по умолчанию, который не оставляет радиокнопок с большой комнате.

Доступ к размеру экземпляров делегата стиля (incrementControl/decrementControl) будет необходим, чтобы найти позицию, по которой текст выровнен по правому краю. Это означает, что вам нужно создать свой собственный SpinBoxStyle, чтобы вы могли предоставить идентификаторы этих экземпляров, чтобы получить к ним доступ в другом месте.

Однако элементы управления не могут удовлетворить каждую проблему, и это довольно специфично. На данный момент может быть проще создать собственный компонент DecimalSpinBox. Затем у вас есть полный контроль над расположением символов и переключателей. Как только вы создадите свой собственный стиль (предыдущий подход, упомянутый выше), вы все равно теряете родной стиль.

+0

Знаете ли вы, как я хотел бы запросить позицию первого символа (или некоторого прокси, чтобы получить меня достаточно близко)? Можно ли найти размер кнопок со стрелками вверх/вниз? Тогда я мог бы просто сместиться с правого конца на эту сумму плюс маржу. – ryan0270

+0

Извините, я забыл про эту часть. Я обновил свой ответ. – Mitch