1
votes

I have a class which is the backend of my application and it does validation checking:

Backend.h

class Backend : public QObject
{
    Q_OBJECT
    Q_PROPERTY(quint8 hours READ getHours WRITE setHours NOTIFY hoursChanged)

public:
    Backend();
    quint8 getHours() const;
    void setHours(quint8 value);
    Q_INVOKABLE void reset();

signals:
    void hoursChanged();

private:
    quint8 m_hours = 0;
};

Backend.cpp

quint8 Backend::getHours() const
{
    return m_hours;
}

void Backend::setHours(quint8 value)
{
    if(m_hours == value)
        return;

    if(value > 23)
        value = 23;

    m_hours = value;
    emit hoursChanged();
}

void Backend::reset()
{
    qDebug() << "reset - old value:" << getHours();
    setHours(0);
}

Now I bound this to a text field this way: main.qml

     TextField {
         id: textFieldHours
         text: backend.hours

         Binding {
             target: backend
             property: "hours"
             value: textFieldHours.text
         }
     }

This works fine and also the boundary check works. If I type a value bigger than 23 it resets to 23. But in this case I also get the message:

qrc:/main.qml:19:5: QML Binding: Binding loop detected for property "value"

Why is that and how can I fix this?

1
I think you are firing hoursChanged every time value is greater than 23. Try to move value validation before comparison with m_hours.Jairo

1 Answers

0
votes

Your code really introduce loop.

To break the "Binding loop" you should call Backend method for auto formatting of text field value on onTextChanged signal:

TextField {
         id: textFieldHours
         onTextChanged: {
              backend.hours = textFieldHours.text
              textFieldHours.text = backend.hours
         }
}

If you need to init TextField with some value from Backend on startup, you can do it in Component.onCompleted: method.

P.S. It seems will be better to implement new method in backend that will take the entered hours as input and return formatted value. Inner implementation can store the changed value in private member.