QML no escribir en C++ de la propiedad cuando se une al componente a y componente de los cambios en el valor

0

Pregunta

Estoy trabajando en un QML proyecto. En la interfaz de usuario en el que estoy trabajando, necesito actualizar regulador de C++, y leer el valor actual en C++ de QML. Propiedades parece ser la solución adecuada. Hasta ahora he leído diferentes preguntas sin éxito Dos vías de enlace C++ modelo en QML, Cambió las Propiedades no de la señal de disparo, etc... En mi actual código que he declarado bien en mi clase de 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;
...
}

Y expuesto en Qt a través de un singleton

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

Entonces obligado el C++ propiedad a un QML control deslizante

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
        }*/
    }
}

El enlace parece que funciona. Puedo modificar el valor de myValue entonces emiten myValueChanged para hacer QML actualización del control deslizante. Pero dado que myClass.myValue está limitada a slider.value. Me asumir ambos valores se actualizan al mismo tiempo. Pero arrastrando el control deslizante de la muestra que tienen valores diferentes. La siguiente es lo que se imprime en la consola cuando arrastro mi slider.

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

Además setMyValue parece no ser llamados a menos explícito de asignación se hace como myClass.myValue = 0. También probé el componente de la Unión, sin éxito. ¿Por qué es este el caso y podría hacer que el C++ de la propiedad actualizado cada vez que me arrastre el control deslizante?

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

Actualización: probado un inversa de unión. Todavía la impresión de que el mismo resultado

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

Para la actualización de C++ propiedad de QML, puede utilizar 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

¿qué sucede cuando myClass.myValue se actualizará y se desencadena su myValueChanged?
folibis

@folibis se actualizará el valor del control deslizante de la propiedad. Por supuesto, el setMyValue el método debe comenzar con la comparación entre un nuevo valor y el valor actual, y emiten myValueChanged sólo si el valor que realmente estaba actualizado. En otro caso, se podía ver un lazo de unión
Jakub Warchoł

Gracias por la respuesta. He probado la solución sugerida. Pero todavía no ver el setter llamado ni el valor de console.log("myClass.myValue = " + myClass.myValue) cambió.
Mary Chang

@MaryChang En el código de arriba, verás console.log("myClass.myValue = " + myClass.myValue) cuando usted va a mover un control deslizante. A ver myClass.myValue valor cambiado, eche un vistazo a las Conexiones de
Jakub Warchoł
0

Aquí es un mínimo ejemplo de trabajo de dos vías de actualización Slider:

main.cpp:

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

de datos.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

Te estás perdiendo la señal cuando se modifica el valor de:

Q_PROPERTY(double myValue READ getMyValue WRITE setMyValue NOTIFY myValueChanged)

Esto significa que la promesa de enviar el myValueChanged la señal siempre el código de C++ cambia el valor. Así que el siguiente debería funcionar:

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

En otros idiomas

Esta página está en otros idiomas

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