Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Disable TextInput update during editing



  • My TextInput is bound to a C++ function, like this:

    TextInput {
        text: MyApp.foo()
    }
    

    of course, I need to disable updates when editing. I tried something like this:

    Item {
        property bool _dirty: false
        property bool _cancel: false
        property string _oldText
    
        TextInput {
            color: _dirty ? "red" : "forestgreen"
            text: {
                var value = MyApp.foo()
                if (_dirty) {
                    if (parseFloat(value) === parseFloat(text)) _dirty = false
                    return text
    
                } else return value === undefined ? "-" : parseFloat(value).toFixed(2)
            }
    
            Keys.onEscapePressed: {
                _cancel = true
                focus = false
            }
    
            onEditingFinished: {
                if (_cancel) {
                    text = _oldText
                    _oldText = ""
                    _dirty = false
                    _cancel = false
    
                } else {
                    MyApp.write(text)
                    focus = false
                }
            }
    
            onActiveFocusChanged: {
                if (activeFocus) {
                    _oldText = text
                    selectAll()
                    _dirty = true
                }
            }
        }
    }
    

    The expected behavior is the following:

    1. normally the text is given by the foo() value, green color
    2. when the user enter in the fields, the color turns red and you can edit the text
    3. if you press 'esc' it ends restoring the previous value and set the green color
    4. if you press 'enter' it calls a C++ functions and waits until the foo() value is equal to the inserted one. When this happens it turns green and binds again with the foo value

    The problem is it complains about a binding loop for property "text".
    It doesn't say the exact line but I might guess is:

    return text
    

    I thought to keep the current value it would be enough to return the actual one. Is it wrong?



  • Hi @Mark81 , here is the sample code:-

    Rectangle {
            id: root
    
            height: 100
            width: 100
            color: "transparent"
            border.color: "red"
    
            property string oldTxt: 'Hello World'
    
            TextInput {
                id: inpTxt
    
                color: activeFocus ? "red" : "forestgreen"
                anchors.fill: parent
    
                Keys.onEscapePressed: {
                    focus = false
                    root.foo('')
                }
    
                Keys.onReturnPressed: {
                    root.oldTxt = inpTxt.text
                    focus = false
                    root.foo(text)
                }
            }
    
            function foo(newText) {
                if(newText === '')
                    inpTxt.text = root.oldTxt
                else
                    inpTxt.text = newText
            }
    
            Component.onCompleted: {
                root.foo('')
            }
        }
    

    Note:- as its just a sample code, i have called the javascript function, you need to call the c++ function as you are doing it now.



  • @Shrinidhi-Upadhyaya thanks for your hints! Out of curiosity, what should be the return value of a property to maintain the current value?



  • @Mark81 , you mean the current text right?It should be a string :-)



  • @Shrinidhi-Upadhyaya said in Disable TextInput update during editing:

    @Mark81 , you mean the current text right?It should be a string :-)

    I mean, if you have a Text object you can set its text property to any value in two ways:

    text: myTextVar
    

    or

    text: { return myTextVar }
    

    the second way allows you do to more complex things, i.e.:

    text: {
        if (myFooVar === 1) return "blabla"
        else if (myFoo2Var === 10) return myTextVar1
        else return myTextVar2
    }
    

    but sometime you might need to leave the value unchanged, I mean keeping the last value. I'm aware I can do it using another variable but it become clumsy:

    text: {
        var currText
        if (myFooVar === 1) currText = "blabla"
        else if (myFoo2Var === 10) currText = myTextVar1
        else currText = oldText // keep the current content
    
        oldText = currText
        return currText
    }
    

    I though it was fine and more readable to return the actual value:

    text: return text
    

    but it creates a binding-loop error (I hoped this case was handled as an exception in order to keep the current value).
    So I wonder if Qt developer provided a way to keep the current value or we need to use another variable like the example above.



  • Hi @Mark81 ,yeah it depends upon how complex things you need to handle, for example if you just need to handle only 2 scenarios like if the value of "myFooVar" is "1", you want to display "Hello" else "Bye" then, you can do like

     text: myFooVar === 1 ? "Hello" : "Bye"
    

    I dont think there is a predefined property or a function to retrieve or store the last value.


Log in to reply