中心文本基于十进制数点的QML类型

时间:2016-09-20 15:25:17

标签: qt text qml center

我有一个简单的Text QML类型:

Item {
    anchors.fill: parent

    Text {
        id: centerText
        text: "6.9"
        anchors.horizontalCenter: parent.horizontalCenter
        y: 570
    }
}

目前,Text将根据字符串的整个长度进行居中。 但我想基于点字符将Text居中。

我在考虑将实际的Text拆分为三个部分:圆形部分,点和小数部分。但是,我不认为我可以将float变量拆分为仅获取小数部分。

是否有其他方式更方便并适应QML

3 个答案:

答案 0 :(得分:2)

以下是如何实现这一目标的快速示例。 “虚拟”隐藏文本用于测量使用Math.floor()获得的数字整数部分的宽度。然后你只需将它定位,使得小数点始终位于父对象的中心,无论数字是什么。

 Column {
    x: 100
    y: 200
    spacing: 5
    Slider {
      id: sl
      width: 400
      minimumValue: 0
      maximumValue: 100
    }
    Rectangle {
      width: 400
      height: 100
      Text {
        x: parent.width * .5 - dummy.width
        y: parent.height * .5 - height * .5
        text: sl.value
        Text {
          id: dummy
          text: Math.floor(sl.value)
          visible: false
        }
      }
    }
  }

enter image description here

顺便说一句,如果你有anchors.fill: parent,则anchors.bottom: parent.bottom是多余的。

答案 1 :(得分:2)

编辑:最后我使用了ddriver的解决方案。如果您使用自定义字体,请不要忘记将其选项包含在虚拟Text中!

我无法重现ddriver的解决方案。我想出了自己的解决方案。我搜索了如何在JavaScript中获取浮点值的小数部分并找到:

(4.89 + "").split(".")[1]; => 89

这比C++ modf函数更方便,因为它没有返回“0”。一部分。

多亏了这一点,我只需创建三种Text QML类型:

// Center horizontally number based on the dot
Text {
    id: testValueRoundPart
    anchors.right: testSpeedDot.left
    y: 570
    text:  (6.9 + "").split(".")[0]
}

Text {
    id: testSpeedDot
    y: 570
    text:  "."
    anchors.horizontalCenter: parent.horizontalCenter
}

Text {
    id: testSpeedValueDecimalPart
    y: 570
    anchors.left: testSpeedDot.right
    text: (6.9 + "").split(".")[1];
}

我一直在使用自定义字体(Sans-Guilt和Universalis;我不认为这些是Monospace字体)并且它有效。 它可能不是最优化的解决方案,但它符合我的需求。

答案 2 :(得分:0)

您可能必须使用类似0的填充之类的东西来实现所需的对齐 - 或者找到等宽字体,然后使用空格而不是0

无论哪种方式 - 这可能是一个解决方案:

import QtQuick 2.0


Item {
      height: 480
      width: 320
      /* list of float strings to pad */
      property var myFloats: ["6.9", "36.21", "4.632", "4225.2", "12.0"]
   

       /*  apply  zero-based padding to the strings on startup
           and output to the console */
      Component.onCompleted: {
           console.log(pad_floats());
      }

   
  /* function takes each decimal,and each integer separated by the .
      and figures out the length of the longest one, then uses
      a padding algorithm to add 0s to the start of the integers
      and 0s to the back of decimals and returns an array */
      function pad_floats() {
          var longest_int = 0;
          var longest_float = 0;
          var newFloats = [];
          for (var i = 0; i < myFloats.length; i++) {
              var tmp_float = myFloats[i];
              var tmp_int = tmp_float.split(".")[0]; // left side
              var tmp_dec = tmp_float.split(".")[1]; // right side

              /* check if either number is more digits than our longest one */
              if (tmp_int.length > longest_int) {
                    longest_int = tmp_int.length;
              }
              if (tmp_dec.length > longest_float) {
                    longest_float = tmp_dec.length;
              }

          }

          for (var u = 0; u < myFloats.length; u++) {
              var tmp_float = myFloats[u];
              var tmp_int = tmp_float.split(".")[0]; // left side of .
              var tmp_dec = tmp_float.split(".")[1]; // right side of .

              /* pad the two numbers */
              var new_int = pad(parseInt(tmp_int), longest_int, "0"); 
              var new_dec = pad(parseInt(tmp_dec), 0 - longest_float, "0");

              /* combine the new numbers back into one */
              var new_float = new_int + "." + new_dec;

              /* add to our array  to return */
              newFloats.push(new_float);

        }
        return newFloats;


  }

  function pad(n, width, z) {
       z = z || '0';
       n = n + '';
       return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
  }

   /*   Heres the ListView to show the actual list of floats */
  ListView {
       width: 320
       height: 480
       anchors.fill: parent
       anchors.left: parent.left
       model: pad_floats()  // our returned array from before
       delegate: listDelegate  // pointer to the Component below


  }

  Component {
      id: listDelegate
      Text {
          text: modelData
          font.pointSize: 11
          verticalAlignment: Text.AlignVCenter
          horizontalAlignment: Text.AlignHCenter
      }
  }

运行此操作的结果是一个ListView,其中包含以下条目:

0006.9
0036.21
0004.632
4225.2
0012.0

就是这样......就像我在答案的顶部说的那样 - 为了创建只有没有额外0的数字的期望结果,你将不得不使用具有相同空间量的字体对于每个角色,包括(空格)角色。

这些通常称为Monotype或Monospace字体。

通常这些字体会将单词“Mono”与其名称相关联,以便更容易找到它们。

找到好的monotype字体后,在pad_floats()函数中替换以下代码:

旧代码

      var new_int = pad(parseInt(tmp_int), longest_int, "0");
      var new_dec = pad(parseInt(tmp_dec), 0 - longest_float, "0");

新代码

      var new_int = pad(parseInt(tmp_int), longest_int, " ");
      var new_dec = pad(parseInt(tmp_dec), 0 - longest_float, " ");

注意我是如何将最后一个“0”参数更改为“”的?最后一个字符串是填充字符串,因此您可以在其中放置任何内容,并使用该字符串填充。

享受。