Home > OS >  Regarding Qml bindings
Regarding Qml bindings

Time:06-18

Why the below code is not working when clicked on cancel button ie., parameterValueText.text is not setting to value 0.

I am assuming both val and parameterValueText.text are binded eachother. If I am wrong, please correct me

Please find below steps
Step 1: Edit a value in Text Input, for ex: 1
Step 2: on Keyboard accepted, parameterValueText.onAccepted is called
Step 3: Click on Save, saveBtn.onClicked is called
Step 4: Click on Cancel, cancelBtn.onClicked is called but the parameterValueText.text is not changed to value 0.

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.VirtualKeyboard 2.1

ApplicationWindow {
id: window
width: 480
height: 272
visible: true
title: qsTr("Keyboard")

property int val: 0

Column {
    Item {
        id: itemId
        height: 20
        width: window.width

        Rectangle{
            width: 100
            height: itemId.height
            border.color:"black"

            TextInput {
                id: parameterValueText
                text: val     //Assuming text and val are  binded ??
                inputMethodHints: Qt.ImhDigitsOnly
                anchors.fill: parent
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
                onAccepted:  console.log("Value = ", parameterValueText.text)

            }
        }
    }

    Row {
        spacing: 10
        Button {
            id: saveBtn
            text: "Save"
            onClicked: console.log("Save = ", parameterValueText.text)
        }

        Button {
            id: cancelBtn
            text: "Cancel"
            onClicked: val = 0 //Why the value is not changing in parameterValueText.text ?
        }
    }
}

InputPanel
{
    id:inputPanel
    y:parent.height
    width: window.width

    //Background for Virtual Keyboard
    Component{
        id:keyboardBackground
        Rectangle{
            color:"#f4f6f3"//ScreenConfiguration.backGroundCanvas
        }
    }
    states: State {
        name: "visible"
        when: inputPanel.active
        PropertyChanges {
            target: inputPanel
            y: parent.height - inputPanel.height
        }
        PropertyChanges {
            target: inputPanel
        }
    }
    transitions: Transition {
        from: ""
        to: "visible"
        reversible: true
        ParallelAnimation {
            NumberAnimation {
                properties: "y"
                duration: 200
                easing.type: Easing.InOutQuad
            }
        }
    }
    Component.onCompleted: {
        keyboard.style.keyboardBackground = keyboardBackground;        // the keyboard background
    }
}

}

main.cpp

int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                 &app, [url](QObject *obj, const QUrl &objUrl) {
    if (!obj && url == objUrl)
        QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);

return app.exec();
}

Add below change in .pro file for enabling virtual keyboard QT = quick virtualkeyboard

The console log ouputs are below qml: Value = 1, val = 0 qml: Save = 1, val = 0

CodePudding user response:

The binding isn't maintained after the user changes the text using the TextInput (as commenters suggested).

To achieve similar results to what you were attempting you could set val in the TextInput's onAccepted slot, and similarly update both val and parameterValueText.text in the onClicked slots for your buttons as appropriate. For example:

    TextInput {
        ...
        onAccepted: {
            val = text
        }
    }
//...
        Button {
            id: cancelBtn
            text: "Cancel"
            onClicked: {
                val = 0;
                parameterValueText.text = val;
            }
        }

This won't maintain the initial bindings because the values are assigned in imperative javascript, but should achieve resetting values as expected.

CodePudding user response:

As continuation on the answer of @dabbler, you can also recreate the binding in the onAccepted handler, but yeah it's still weird.

 parameterValueText.text = Qt.binding(function() { return val; })

As another solution, you could have the val property bind to the text of the input (which then starts with "0"):

readonly property int val: parseInt(parameterValueText.text)

But that only works if the val property is intended to be used as readonly (otherwise you will loose the binding again). In case you want the val property to be set from outside, you could do the following:

onValChanged: parameterValueText.text = val

Note that this is assignment, not binding!

  • Related