我有一个简单的Text
QML
类型:
Item {
anchors.fill: parent
Text {
id: centerText
text: "6.9"
anchors.horizontalCenter: parent.horizontalCenter
y: 570
}
}
目前,Text
将根据字符串的整个长度进行居中。
但我想基于点字符将Text
居中。
我在考虑将实际的Text
拆分为三个部分:圆形部分,点和小数部分。但是,我不认为我可以将float
变量拆分为仅获取小数部分。
是否有其他方式更方便并适应QML
?
答案 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
}
}
}
}
顺便说一句,如果你有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”参数更改为“”的?最后一个字符串是填充字符串,因此您可以在其中放置任何内容,并使用该字符串填充。
享受。