Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用DoubleValidator防止QML SpinBox中的中间文本值超出范围?_Python_Qt_Pyqt_Qml_Pyqt5 - Fatal编程技术网

Python 如何使用DoubleValidator防止QML SpinBox中的中间文本值超出范围?

Python 如何使用DoubleValidator防止QML SpinBox中的中间文本值超出范围?,python,qt,pyqt,qml,pyqt5,Python,Qt,Pyqt,Qml,Pyqt5,我正在尝试创建一个可编辑的浮点SpinBox QML元素。除了可以键入数字,使SpinBox中的文本显示无效值(例如,最大值为100时为105)之外,所有这些功能都可以正常工作。我试着用Keys.onPressed捕捉按键,但这似乎不可能。我还尝试使用像onTextChanged这样的信号,但对于SpinBox来说这似乎并不存在。最后,我尝试将QValidator子类化,并将其用作spinbox的验证器,但出现了“无法将对象分配给属性”错误。我假设这是因为我创建的自定义验证器不是验证器QML类型

我正在尝试创建一个可编辑的浮点SpinBox QML元素。除了可以键入数字,使SpinBox中的文本显示无效值(例如,最大值为100时为105)之外,所有这些功能都可以正常工作。我试着用Keys.onPressed捕捉按键,但这似乎不可能。我还尝试使用像onTextChanged这样的信号,但对于SpinBox来说这似乎并不存在。最后,我尝试将QValidator子类化,并将其用作spinbox的验证器,但出现了“无法将对象分配给属性”错误。我假设这是因为我创建的自定义验证器不是验证器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")
spinbox 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
    }
}

我找到了问题的答案。我找到了SpinBox QML元素的源代码,并复制了TextInput
contentItem
的代码。然后,我在
onTextEdited
中编写了一个快速函数,它根据微调框中的
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
        }
    }
}
导入QtQuick.Controls.impl 2.2
旋转箱{
id:spinbox
...
contentItem:TextInput{
id:spinboxTextInput
属性字符串oldText:spinboxTextInput.text
z:2
text:spinbox.textFromValue(spinbox.value,spinbox.locale)
不透明度:spinbox.enabled?1:0.3
字体:spinbox.font
颜色:Default.textColor
selectionColor:Default.focusColor
selectedTextColor:Default.textLightColor
水平对齐:Qt.AlignHCenter
垂直对齐:Qt.AlignVCenter
只读:!spinbox.editable
验证器:spinbox.validator
InputMethodHists:spinbox.InputMethodHists
//检查新文本的值,如果超出范围,则返回
onTextEdited:{
var val=spinbox.valueFromText(spinboxTextInput.text,spinbox.locale)
if(valspinbox.to){
spinboxTextInput.text=spinboxTextInput.oldText
}
否则{
spinboxTextInput.oldText=spinboxTextInput.text
}
}
长方形{
x:-6-(spinbox.down.indicator?1:0)
y:-6
宽度:spinbox.width-(spinbox.up.indicator?spinbox.up.indicator.width-1:0)-(spinbox.down.indicator?spinbox.down.indicator.width-1:0)
高度:spinbox.height
可见:spinbox.activeFocus
颜色:“透明”
border.color:Default.focusColor
边框宽度:2
}
}
}