我试图制作一个可编辑的浮点SpinBox QML元素。这一切都有效,除了可以键入数字以使SpinBox中的文本显示无效值(例如,当max为100时为105)。我试图用Keys.onPressed抓住按键,但这似乎不可能。我也尝试使用像onTextChanged这样的信号,但对于SpinBox来说似乎并不存在。最后,我尝试将QValidator子类化并将其用作spinbox的验证器,但我得到了"无法将对象分配给属性"错误。我认为这是因为我制作的自定义验证器不是Validator QML类型。
spinbox-test.py
import sys
from PyQt5 import QtGui
from PyQt5.QtQml import QQmlApplicationEngine, qmlRegisterType
from PyQt5.QtWidgets import QApplication
class MyDoubleValidator(QtGui.QValidator):
def __init__(self, parent=None):
QtGui.QValidator.__init__(self, parent)
print("Validator created")
def validate(self, inputStr, pos):
print("validating")
if len(inputStr) > 2:
return (QtGui.QValidator.Invalid, pos)
elif len(inputStr) == 0:
return (Qt.QValidator.Intermediate, pos)
else:
return (Qt.Qvalidator.Acceptable, pos)
app = QApplication(sys.argv)
qmlRegisterType(MyDoubleValidator, 'MyValidators', 1, 0, 'MyDoubleValidator')
engine = QQmlApplicationEngine()
engine.load("spinbox-test.qml")
纺纱器-test.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import MyValidators 1.0
ApplicationWindow {
visible: true
title: qsTr("Spinbox Test")
width: 400
height: 350
color: "whitesmoke"
Item {
id: doubleSpinbox
property int decimals: 2
property real realValue: 1.1
property real realFrom: 0.0
property real realTo: 100.0
property real realStepSize: 1.0
anchors.centerIn: parent
SpinBox {
id: spinbox
property real factor: Math.pow(10, doubleSpinbox.decimals)
stepSize: doubleSpinbox.realStepSize * spinbox.factor
value: doubleSpinbox.realValue * spinbox.factor
to: doubleSpinbox.realTo * spinbox.factor
from: doubleSpinbox.realFrom * spinbox.factor
editable: true
onValueChanged: label.text = spinbox.value / spinbox.factor
validator: MyDoubleValidator { }
textFromValue: function(value, locale) {
return parseFloat(spinbox.value*1.0/spinbox.factor).toFixed(doubleSpinbox.decimals);
}
}
}
Label {
id: label
text: doubleSpinbox.realValue
}
}
答案 0 :(得分:0)
我找到了问题的答案。我找到了SpinBox QML元素的源代码,并复制了TextInput contentItem
的代码。然后我在onTextEdited
中编写了一个快速函数,用于检查SpinBox中to
和from
的值。它不是最可重复使用的解决方案,但它只是我所需要的。另外,请务必导入QtQuick.Control.impl
以获取默认值。
import QtQuick.Controls.impl 2.2
SpinBox {
id: spinbox
...
contentItem: TextInput {
id: spinboxTextInput
property string oldText: spinboxTextInput.text
z: 2
text: spinbox.textFromValue(spinbox.value, spinbox.locale)
opacity: spinbox.enabled ? 1 : 0.3
font: spinbox.font
color: Default.textColor
selectionColor: Default.focusColor
selectedTextColor: Default.textLightColor
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !spinbox.editable
validator: spinbox.validator
inputMethodHints: spinbox.inputMethodHints
//Check the value of the new text, and revert back if out of range
onTextEdited: {
var val = spinbox.valueFromText(spinboxTextInput.text, spinbox.locale)
if (val < spinbox.from || val > spinbox.to) {
spinboxTextInput.text = spinboxTextInput.oldText
}
else {
spinboxTextInput.oldText = spinboxTextInput.text
}
}
Rectangle {
x: -6 - (spinbox.down.indicator ? 1 : 0)
y: -6
width: spinbox.width - (spinbox.up.indicator ? spinbox.up.indicator.width - 1 : 0) - (spinbox.down.indicator ? spinbox.down.indicator.width - 1 : 0)
height: spinbox.height
visible: spinbox.activeFocus
color: "transparent"
border.color: Default.focusColor
border.width: 2
}
}
}