QML non scrivere in C++ proprietà quando è legata ad un componente e componente variazioni di valore

0

Domanda

Sto lavorando su un QML progetto. Nell'interfaccia utente a cui sto lavorando, ho bisogno sia di aggiornare il dispositivo di scorrimento da C++ e leggere il valore della corrente in C++ da QML. Proprietà sembra essere la soluzione giusta. Finora ho letto diverse domande su COSÌ senza successo Due modo vincolante C++ modello in QML, Cambiato Proprietà non segnale di trigger, ecc... Nel mio attuale codice che ho dichiarato un immobile nella mia 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;
...
}

E esposto in Qt tramite un singleton

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

Quindi associata delle proprietà di C++ per un QML dispositivo di scorrimento

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

L'associazione sembra funzionare. Sono in grado di modificare il valore di myValue quindi emettono myValueChanged per rendere QML aggiornare il dispositivo di scorrimento. Ma dato che myClass.myValue è delimitata a slider.value. Mi piacerebbe assumere entrambi i valori vengono aggiornati allo stesso tempo. Ma trascinando il dispositivo di scorrimento indica che hanno valori diversi. Il seguente è ciò che viene stampato nella console quando ho trascinare il dispositivo di scorrimento.

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

Inoltre setMyValue sembra non essere chiamati a meno che un'esplicita assegnazione è fatta come myClass.myValue = 0. Ho provato anche il componente per l'Associazione, senza successo. Perché è questo il caso e potrei fare il C++ proprietà aggiornata ogni volta che ho trascinare il dispositivo di scorrimento?

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

Aggiornamento: provato una associazione inversa. Ancora la stampa lo stesso risultato

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

Per aggiornare le proprietà di C++ da QML, è possibile utilizzare 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

cosa succede quando myClass.myValue sarà aggiornato e verrà generato l' myValueChanged?
folibis

@folibis aggiornare il dispositivo di scorrimento di valore di proprietà. Naturalmente, il setMyValue metodo dovrebbe iniziare con un confronto tra un valore e il valore corrente, ed emettono myValueChanged solo se il valore è stato veramente aggiornato. In altri casi, si potrebbe vedere un ciclo di associazione
Jakub Warchoł

Grazie per la risposta. Ho provato la soluzione suggerita. Ma ancora non vedendo il setter chiamato né il valore di console.log("myClass.myValue = " + myClass.myValue) cambiato.
Mary Chang

@MaryChang Nel codice di cui sopra, si vedrà console.log("myClass.myValue = " + myClass.myValue) quando si sposta un cursore. Per vedere myClass.myValue cambiato il valore, avere uno sguardo alle Connessioni
Jakub Warchoł
0

Ecco un minimo di lavoro esempio di due vie di aggiornamento di Scorrimento:

main.cpp:

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

dati.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();
    }
}

principale.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

Ti manca il segnale quando si modifica il valore:

Q_PROPERTY(double myValue READ getMyValue WRITE setMyValue NOTIFY myValueChanged)

Questo significa che la promessa è necessario inviare il myValueChanged segnale ogni volta che il codice C++ cambia il valore. Quindi, il seguente dovrebbe funzionare:

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

In altre lingue

Questa pagina è in altre lingue

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