QML nu scrie la C++ proprietate, atunci când legat de componentă și componentă modificările de valoare

0

Problema

Lucrez la un QML proiect. În UI lucrez, am nevoie de atât de actualizare slider din C++ și citește valoarea curentă în C++ de la QML. Proprietăți pare a fi soluția potrivită. Până acum am citit diferite întrebări pe ATÂT de fără succes Două mod obligatoriu C++ model în QML, Schimbat Proprietăți nu declanșa semnalul, etc... În actualul cod în care am declarat-o proprietate în C++ clasa

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;
...
}

Și expuse în Qt printr-un singleton

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

Apoi legat de C++ de proprietate de la un QML slider

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

Legarea pare să funcționeze. Nu pot modifica valoarea myValue apoi emit myValueChanged pentru a face QML actualizare slider. Dar având în vedere că myClass.myValue este delimitată de slider.value. Aș presupune că ambele valori se actualizează în același timp. Dar glisarea cursorului arată că acestea au valori diferite. Următoarele este ceea ce este imprimat în consola cand mi târăsc slider.

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

În plus setMyValue pare să nu fie numit, cu excepția cazului în mod explicit atribuirea se face ca myClass.myValue = 0. Am încercat, de asemenea, Obligatoriu componentă fără succes. De ce este acest caz și am putut să fac C++ proprietate actualizat ori de câte ori mă trageți cursorul?

Qt: 6.2.1
Compilator: zăngănit/gcc
Sistem de OPERARE: Windows/Linux

Update: testat un revers obligatorii. Încă de imprimare același rezultat

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

Pentru a actualiza C++ proprietate de la QML, puteți utiliza 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 se întâmplă atunci când myClass.myValue va fi actualizat și va foc myValueChanged?
folibis

@folibis Se va actualiza valoarea glisorului de proprietate. Desigur, setMyValue metoda ar trebui să înceapă cu o comparație între o nouă valoare și valoarea curentă, și emit myValueChanged numai dacă valoarea a fost actualizat. În alt caz, ai putea vedea o buclă de legare
Jakub Warchoł

Multumesc pentru raspuns. Am încercat soluția propusă. Dar încă nu văd setter sunat și nici valoarea de console.log("myClass.myValue = " + myClass.myValue) s-a schimbat.
Mary Chang

@MaryChang În codul de mai sus, veți vedea console.log("myClass.myValue = " + myClass.myValue) atunci când se va muta un cursor. Pentru a vedea myClass.myValue valoarea schimbat, au o privire la Conexiuni
Jakub Warchoł
0

Aici e un minim exemplu de lucru de două mod de actualizare Slider:

main.cpp:

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

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

Pierzi semnalul când modificați valoarea:

Q_PROPERTY(double myValue READ getMyValue WRITE setMyValue NOTIFY myValueChanged)

Acest lucru înseamnă că vă promit că vă voi trimite myValueChanged semnal ori de câte ori C++ cod schimbă valoarea. Deci, următoarele ar trebui să funcționeze:

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

În alte limbi

Această pagină este în alte limbi

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