QML ne pas écrire en C++ de la propriété quand il est lié à la composante et la valeur des composantes des changements

0

La question

Je suis en train de travailler sur un QML projet. Dans l'INTERFACE utilisateur sur lequel je travaille, j'ai besoin à la fois de mettre à jour curseur à partir de C++ et de lire la valeur actuelle en C++ à partir de QML. Propriétés semble être la bonne solution. Jusqu'à présent, j'ai lu différentes questions sur sans succès les Deux sens de la liaison C++ modèle dans QML, Modifié les Propriétés ne déclenchent pas de signal, etc... Dans mon code, je l'ai déclaré " bien dans ma classe C++

class MyClass : public QObject {
    Q_OBJECT
public:
    MyClass(QObject*);
    Q_PROPERTY(double myValue READ getMyValue WRITE setMyValue NOTIFY myValueChanged)

    void setMyValue(double n) {
        std::cerr << "myValue  being update: " << n << "\n";
        myValue = n;
    }

    double myValue = 30;
...
}

Et exposée dans Qt par l'intermédiaire d'un singleton

qmlRegisterSingletonInstance("com.me.test", 1, 0, "MyClass", &myClass);

Ensuite lié les propriétés de C++ à un QML curseur

import com.me.test
ApplicationWindow {
    Slider {
        id: slider
        height: 30
        width: 100
        from: 0
        to: 100
        value: myClass.myValue
        onValueChanged {
            console.log("value = " + value)
            console.log("myClass.myValue = " + myClass.myValue)
        }

        /* Doesn't help
        Binding {
            target: slider
            property: "value"
            value: myClass.myValue
        }*/
    }
}

La liaison semble fonctionner. Je peux modifier la valeur de myValue puis émettent myValueChanged pour faire QML mise à jour c'est curseur. Mais étant donné que myClass.myValue est bornée à slider.value. Je suppose que les deux valeurs est mise à jour en même temps. Mais en faisant glisser le curseur indique qu'ils ont des valeurs différentes. La suite de ce qui est imprimé sur la console, si je fais glisser mon curseur.

qml: value = 19.863013698630137
qml: myClass.myValue = 30

En outre setMyValue il semble ne pas être appelé, à moins qu'une affectation explicite est faite comme myClass.myValue = 0. J'ai aussi essayé le composant de Liaison sans succès. Pourquoi est-ce le cas et si je pouvais faire le C++ propriété mise à jour à chaque fois que je fais glisser le curseur?

Qt: 6.2.1
Compilateur clang/gcc
OS: Windows/Linux

Mise à jour: testé un revers de liaison. Toujours l'impression de le même résultat

import com.me.test
ApplicationWindow {
    Slider {
        id: slider
        height: 30
        width: 100
        from: 0
        to: 100
        value: myClass.myValue
        onValueChanged {
            console.log("value = " + value)
            console.log("myClass.myValue = " + myClass.myValue)
        }
        Binding {
            target: myClass
            property: "myValue"
            value: slider.value
        }
    }
}
c++ qml qt qt6
2021-11-24 06:49:49
3
0

Pour mettre à jour les propriétés de C++ à partir de QML, vous pouvez utiliser Binding:

import com.me.test
ApplicationWindow {
    Slider {
        id: slider
        height: 30
        width: 100
        from: 0
        to: 100
        value: myClass.myValue
        onValueChanged {
            console.log("value = " + value)
            console.log("myClass.myValue = " + myClass.myValue)
        }
         // C++ property was bounded to QML above, now we should bind QML to C++
        Binding {
            target: myClass 
            property: "myValue"
            value: slider.value
        }
    }
}
2021-11-24 09:12:14

ce qui se passe quand myClass.myValue sera mis à jour et déclenche son myValueChanged?
folibis

@folibis Il mettra à jour la valeur de la barre de propriété. Bien sûr, la setMyValue la méthode doit commencer avec une comparaison entre une valeur et la valeur actuelle, et émettent myValueChanged seulement si la valeur a été vraiment mis à jour. Dans d'autres cas, vous pourriez voir une boucle de liaison
Jakub Warchoł

Merci pour la réponse. J'ai essayé la solution proposée. Mais toujours pas à voir le setter appelé ni la valeur de console.log("myClass.myValue = " + myClass.myValue) changé.
Mary Chang

@MaryChang Dans le code ci-dessus, vous verrez console.log("myClass.myValue = " + myClass.myValue) lorsque vous déplacez un curseur. Pour voir myClass.myValue valeur a changé, avoir un regard sur les Connexions
Jakub Warchoł
0

Voici un minimum de travail exemple de deux façon la mise à jour de Curseur:

main.cpp:

data dataObj;
engine.rootContext()->setContextProperty("dataCpp", (QObject*)&dataObj);

les données.h:

class data : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
public:
    explicit data(QObject *parent = nullptr);
    int value(void);
    void setValue(int new_value);
public slots:
    void reset(void);
signals:
    void valueChanged();
private:
    int dataValue;
};

data.cpp:

data::data(QObject *parent) : QObject(parent)
{
    dataValue = 250;
}

int data::value()
{
    return dataValue;
}

void data::setValue(int new_value)
{
    if(dataValue != new_value)
    {
        qDebug() << "setting" << new_value;
        dataValue = new_value;
        emit valueChanged();
    }
}

void data::reset()
{
    if(dataValue != 0)
    {
        qDebug() << "resetting to 0";
        dataValue = 0;
        emit valueChanged();
    }
}

principal.qml:

Slider {
    id: slider
    height: 50
    width: 500
    from: 0
    to: 500
    live: false
    value: dataCpp.value
    onValueChanged: dataCpp.value = value
}

Button{
    anchors.top: slider.bottom
    text: "Reset"
    onPressed: dataCpp.reset()
}
2021-12-14 13:21:29
0

Il vous manque le signal lors de la modification de la valeur:

Q_PROPERTY(double myValue READ getMyValue WRITE setMyValue NOTIFY myValueChanged)

Cela signifie que vous promets que vous allez envoyer l' myValueChanged signal chaque fois que le code C++ du changement de valeur. Donc, la suivante devrait fonctionner:

void setMyValue(double n) {
    std::cerr << "myValue  being update: " << n << "\n";
    myValue = n;
    emit(myValueChanged());
}
2021-12-14 15:18:53

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................