QML 文本始终显示小数位
QML text always display decimal places
我在下面有一些 QML,我希望始终确保始终显示小数点后百分之一的值。目前,当你点击红色的大按钮时,顶部的数字会增加 1。如果按住按钮,有一个计时器可以帮助在按住按钮时重复递增数字。
我正在使用浮点数据类型,每次调用某种增量时,尾随的 0 都会消失。但是,我需要显示那些 0。所以我尝试在 onClicked 和 onPressAndHold 信号中插入一些 Javascript,但是我注释掉的行 displayVal.text = result
会导致数字停止递增。是我的逻辑有问题,还是有更好的方法来添加尾随 0?我不妨还提到,仅在所有内容的末尾附加“.00”是行不通的,因为将来我将处理不完整的十进制数字,例如 10.20 或 11.89。我也不太熟悉 Javascript,所以我当前尝试添加 0 的代码片段来自另一个论坛 post。我知道它部分有效,至少是因为打印语句。
如果可能的话,我想尽可能避免复杂Javascript;复杂到需要功能什么的。如果这甚至可以在 Python 代码中处理,那就更好了。
main.qml:
import QtQuick 2.14
import QtQuick.Layouts 1.12
import QtQuick.Controls.Material 2.15
Item {
visible: true
width: 600; height: 400
id: itemView
signal startIncrement()
signal stopIncrement()
signal incrementOnce()
ColumnLayout{
Repeater{
model: modelManager.model
ColumnLayout{
Text {
id: displayVal
text: model.display
font.pixelSize: 30
}
Rectangle{
id: incrementButton
color: "red"
width: 250
height: 100
MouseArea {
anchors.fill: parent
onClicked: {
incrementOnce()
var num = parseFloat(displayVal.text)
var result = num.toFixed(Math.max(2, (num.toString().split('.')[1] || []).length));
// displayVal.text = result
console.log("OnClick Formatted #: " + result + " DisplayVal: " + displayVal.text)
}
onPressAndHold:{
startIncrement()
var num = parseFloat(displayVal.text)
var result = num.toFixed(Math.max(2, (num.toString().split('.')[1] || []).length));
// displayVal.text = result
console.log("Started increment")
}
onReleased:{
stopIncrement()
console.log("Stopped increment")
}
}
}
}
}
}
}
main.py:
import os
import sys
from pathlib import Path
sys.path.append(os.path.join(os.path.dirname(sys.path[0]), ".."))
from PySide6.QtCore import QUrl, Qt, QCoreApplication, QTimer, QObject, Property
from PySide6.QtGui import QGuiApplication, QStandardItemModel, QStandardItem
from PySide6.QtQuick import QQuickView
CURRENT_DIRECTORY = Path(__file__).resolve().parent
DisplayRole = Qt.UserRole
class ModelManager(QObject):
def __init__(self):
super().__init__()
self._model = QStandardItemModel()
self._model.setItemRoleNames({DisplayRole: b"display"})
item = QStandardItem()
item.setData("10.00", DisplayRole)
self._model.appendRow(item)
self.timer = QTimer()
self.timer.setInterval(100)
@Property(QObject, constant=True)
def model(self):
return self._model
def start_increment(self):
self.timer.timeout.connect(self.increment)
self.timer.start()
def increment(self):
presentVal = float(self._model.item(0).data(DisplayRole)) +1.0
self._model.item(0).setData(presentVal, DisplayRole)
print(presentVal)
def stop_increment(self):
if self.timer.isActive():
self.timer.stop()
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
url = QUrl.fromLocalFile(os.fspath(CURRENT_DIRECTORY / "main.qml"))
def handle_status_changed(status):
if status == QQuickView.Error:
QCoreApplication.exit(-1)
modelManager = ModelManager()
view.rootContext().setContextProperty("modelManager", modelManager)
view.statusChanged.connect(handle_status_changed, Qt.ConnectionType.QueuedConnection)
view.setSource(url)
root = view.rootObject()
root.startIncrement.connect(modelManager.start_increment)
root.stopIncrement.connect(modelManager.stop_increment)
root.incrementOnce.connect(modelManager.increment)
view.show()
sys.exit(app.exec())
问题是,当您执行 displayVal.text = result
时,您会停止自动更新模型中显示的文本的能力。结果是,当模型更新时,显示文本不会,因为您为此设置了一个静态值。
解决方法是在text
定义中直接使用toFixed
:
Text {
id: displayVal
text: model.display.toFixed(2)
font.pixelSize: 30
}
和将项目的值设置为数字,而不是字符串:
item.setData(10., DisplayRole)
这显然意味着您必须删除在 incrementOnce
和 startIncrement
之后尝试实现的所有计算,因为它不再是不必要的。
注意:
- 您不应该覆盖现有的
display
角色,如果绝对必要,您应该使用另一个名称;实际上,您可以避免设置角色名称并使用标准 Qt.DisplayRole
设置数字(同样,不是字符串);
- 在
start_increment
函数中连接定时器是一个错误,因为它会导致每次连接时调用increment
:如果你按两次按钮,就会增加两次,如果按三下,它将递增 3,依此类推。移动 __init__
; 中的连接
我在下面有一些 QML,我希望始终确保始终显示小数点后百分之一的值。目前,当你点击红色的大按钮时,顶部的数字会增加 1。如果按住按钮,有一个计时器可以帮助在按住按钮时重复递增数字。
我正在使用浮点数据类型,每次调用某种增量时,尾随的 0 都会消失。但是,我需要显示那些 0。所以我尝试在 onClicked 和 onPressAndHold 信号中插入一些 Javascript,但是我注释掉的行 displayVal.text = result
会导致数字停止递增。是我的逻辑有问题,还是有更好的方法来添加尾随 0?我不妨还提到,仅在所有内容的末尾附加“.00”是行不通的,因为将来我将处理不完整的十进制数字,例如 10.20 或 11.89。我也不太熟悉 Javascript,所以我当前尝试添加 0 的代码片段来自另一个论坛 post。我知道它部分有效,至少是因为打印语句。
如果可能的话,我想尽可能避免复杂Javascript;复杂到需要功能什么的。如果这甚至可以在 Python 代码中处理,那就更好了。
main.qml:
import QtQuick 2.14
import QtQuick.Layouts 1.12
import QtQuick.Controls.Material 2.15
Item {
visible: true
width: 600; height: 400
id: itemView
signal startIncrement()
signal stopIncrement()
signal incrementOnce()
ColumnLayout{
Repeater{
model: modelManager.model
ColumnLayout{
Text {
id: displayVal
text: model.display
font.pixelSize: 30
}
Rectangle{
id: incrementButton
color: "red"
width: 250
height: 100
MouseArea {
anchors.fill: parent
onClicked: {
incrementOnce()
var num = parseFloat(displayVal.text)
var result = num.toFixed(Math.max(2, (num.toString().split('.')[1] || []).length));
// displayVal.text = result
console.log("OnClick Formatted #: " + result + " DisplayVal: " + displayVal.text)
}
onPressAndHold:{
startIncrement()
var num = parseFloat(displayVal.text)
var result = num.toFixed(Math.max(2, (num.toString().split('.')[1] || []).length));
// displayVal.text = result
console.log("Started increment")
}
onReleased:{
stopIncrement()
console.log("Stopped increment")
}
}
}
}
}
}
}
main.py:
import os
import sys
from pathlib import Path
sys.path.append(os.path.join(os.path.dirname(sys.path[0]), ".."))
from PySide6.QtCore import QUrl, Qt, QCoreApplication, QTimer, QObject, Property
from PySide6.QtGui import QGuiApplication, QStandardItemModel, QStandardItem
from PySide6.QtQuick import QQuickView
CURRENT_DIRECTORY = Path(__file__).resolve().parent
DisplayRole = Qt.UserRole
class ModelManager(QObject):
def __init__(self):
super().__init__()
self._model = QStandardItemModel()
self._model.setItemRoleNames({DisplayRole: b"display"})
item = QStandardItem()
item.setData("10.00", DisplayRole)
self._model.appendRow(item)
self.timer = QTimer()
self.timer.setInterval(100)
@Property(QObject, constant=True)
def model(self):
return self._model
def start_increment(self):
self.timer.timeout.connect(self.increment)
self.timer.start()
def increment(self):
presentVal = float(self._model.item(0).data(DisplayRole)) +1.0
self._model.item(0).setData(presentVal, DisplayRole)
print(presentVal)
def stop_increment(self):
if self.timer.isActive():
self.timer.stop()
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
url = QUrl.fromLocalFile(os.fspath(CURRENT_DIRECTORY / "main.qml"))
def handle_status_changed(status):
if status == QQuickView.Error:
QCoreApplication.exit(-1)
modelManager = ModelManager()
view.rootContext().setContextProperty("modelManager", modelManager)
view.statusChanged.connect(handle_status_changed, Qt.ConnectionType.QueuedConnection)
view.setSource(url)
root = view.rootObject()
root.startIncrement.connect(modelManager.start_increment)
root.stopIncrement.connect(modelManager.stop_increment)
root.incrementOnce.connect(modelManager.increment)
view.show()
sys.exit(app.exec())
问题是,当您执行 displayVal.text = result
时,您会停止自动更新模型中显示的文本的能力。结果是,当模型更新时,显示文本不会,因为您为此设置了一个静态值。
解决方法是在text
定义中直接使用toFixed
:
Text {
id: displayVal
text: model.display.toFixed(2)
font.pixelSize: 30
}
和将项目的值设置为数字,而不是字符串:
item.setData(10., DisplayRole)
这显然意味着您必须删除在 incrementOnce
和 startIncrement
之后尝试实现的所有计算,因为它不再是不必要的。
注意:
- 您不应该覆盖现有的
display
角色,如果绝对必要,您应该使用另一个名称;实际上,您可以避免设置角色名称并使用标准Qt.DisplayRole
设置数字(同样,不是字符串); - 在
start_increment
函数中连接定时器是一个错误,因为它会导致每次连接时调用increment
:如果你按两次按钮,就会增加两次,如果按三下,它将递增 3,依此类推。移动__init__
; 中的连接