Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Other class read unchanged variable value



  • In my app I have 5 async loops. To keep GUI without laggs I made new Thread just for those loops. In config.h file b_drink variable and Q_PROPERTY to read and write to this variable from QML.

    Q_PROPERTY(bool b_drink READ r_drink WRITE w_drink);
    
    public:
        explicit Config(QObject *parent = nullptr);
        Q_PROPERTY(bool b_drink READ r_drink WRITE w_drink);
    
        bool b_drink = false;
        bool r_drink(){
            return b_drink;
        }
    
    public slots:
        void save();
        void load();
    
        void w_drink(bool value){    
            qDebug() << "Current value is: " << b_drink << ", changing to: " << value;
            b_drink = value;
        }
    
    Switch {
        id: control
        x: -13
        y: 43
        checked: Config.b_drink
        onClicked:{
            console.log(control.checked);
            Config.w_drink(control.checked);
        }
    }
    

    Logs from Application Output (false spam is from loop in other class and thread):

    QQmlExpression: Expression qrc:/main.qml:104:17 depends on non-NOTIFYable properties:
        Config::b_drink
    qrc:/main.qml:174:13: Unable to assign [undefined] to bool
    qrc:/main.qml:242:13: Unable to assign [undefined] to bool
    qrc:/main.qml:310:13: Unable to assign [undefined] to bool
    qrc:/main.qml:378:13: Unable to assign [undefined] to bool
    false
    false
    false
    qml: true
    Current value is:  false , changing to:  true
    false
    false
    false
    false
    false
    false
    false
    qml: false
    Current value is:  true , changing to:  false
    false
    qml: true
    Current value is:  false , changing to:  true
    false
    false
    

  • Moderators

    @BD9a I'm not entirely sure, what's going, or to be precise why everything doesn't go up in flames, but it is running on my pc and it shoudn't.

    You can force this on your side as well by properly initializing the Config * inside Loop to a nullptr.

    private:
        Config *config = nullptr;
    
    

    that will crash, and it should.

    Here, what to do to fix this:

    Enable writing & storing

    void Config::w_drink(bool value)
    {
        qDebug() << "Current value is: " << b_drink;
        if( b_drink == value)
             return;
    
        b_drink = value;
        //emit stateChanged(value);
    }
    

    Pass the Config object on (from main.cpp) on. for example like this:

    //loop.h
    explicit Loop(Config *conf, QObject *parent = nullptr);
    ...
    private:
        Config *config = nullptr; 
    
    //loop.cpp
    Loop::Loop(Config *conf, QObject *parent) 
          : QObject(parent) , config(conf){
        flaskNo1 = new QTimer(this);
        flaskNo2 = new QTimer(this);
        flaskNo3 = new QTimer(this);
        flaskNo4 = new QTimer(this);
        flaskNo5 = new QTimer(this);
    
        connect(flaskNo1, SIGNAL(timeout()),this,SLOT(drinkNo1()));
        connect(flaskNo2, SIGNAL(timeout()),this,SLOT(drinkNo2()));
        connect(flaskNo3, SIGNAL(timeout()),this,SLOT(drinkNo3()));
        connect(flaskNo4, SIGNAL(timeout()),this,SLOT(drinkNo4()));
        connect(flaskNo5, SIGNAL(timeout()),this,SLOT(drinkNo5()));
    
        startLoop();
    }
    
    //main.cpp
    ...
        Config config;
        config.create();
    
        KeyTranslator ktr;
        Loop loop(&config);
    ...
    

  • Moderators

    @BD9a said in Other Thread in my app dont get changed variable value:

    QQmlExpression: Expression qrc:/main.qml:104:17 depends on non-NOTIFYable properties:

    You need to add NOTIFY to your Q_PROPERTY and add a signal (and remeber to emit it when value changes!).



  • @sierdzio its necessary in this case? I have exacly same config in other project, and it work good


  • Moderators

    @BD9a said in Other Thread in my app dont get changed variable value:

    @sierdzio its necessary in this case? I have exacly same config in other project, and it work good

    Yes. Without NOTIFY, QML engine has no idea that value has updated.



  • @sierdzio It could be useful, but I dont think it's my problem. In other project Q_PROPERTY without NOTIFY work's good, and probably one strong diffrence is that additional thread.

    b_drink variable is changing it's value, but function in other thread reading unchanged value.

    Removed this additional Thread (I dont really need this, those loops operate on ~3sec interval) and saw sth really weird. I changed this button to just print b_dring variable value (hardcoded as false) - in same class it prints false, in loop class it printing true wtf...


  • Moderators

    @BD9a minimal compileable example, please.



  • There is current code:
    https://github.com/BD9a/test

    Loop/loop.cpp printing b_drink defined in Config/config.h


  • Qt Champions 2019

    Are you sure your testapp does not crash? 'Config *config;' is unitialized...



  • @Christian-Ehrlicher It doesnt crash

    Current value is:  false
    true
    true
    true
    

  • Qt Champions 2019

    @BD9a Please fix your code, it can't work as I already explained.



  • @Christian-Ehrlicher how it should be done? In my opinion it should work (maybe cuz I dont understand it well?)


  • Moderators

    @BD9a I'm not entirely sure, what's going, or to be precise why everything doesn't go up in flames, but it is running on my pc and it shoudn't.

    You can force this on your side as well by properly initializing the Config * inside Loop to a nullptr.

    private:
        Config *config = nullptr;
    
    

    that will crash, and it should.

    Here, what to do to fix this:

    Enable writing & storing

    void Config::w_drink(bool value)
    {
        qDebug() << "Current value is: " << b_drink;
        if( b_drink == value)
             return;
    
        b_drink = value;
        //emit stateChanged(value);
    }
    

    Pass the Config object on (from main.cpp) on. for example like this:

    //loop.h
    explicit Loop(Config *conf, QObject *parent = nullptr);
    ...
    private:
        Config *config = nullptr; 
    
    //loop.cpp
    Loop::Loop(Config *conf, QObject *parent) 
          : QObject(parent) , config(conf){
        flaskNo1 = new QTimer(this);
        flaskNo2 = new QTimer(this);
        flaskNo3 = new QTimer(this);
        flaskNo4 = new QTimer(this);
        flaskNo5 = new QTimer(this);
    
        connect(flaskNo1, SIGNAL(timeout()),this,SLOT(drinkNo1()));
        connect(flaskNo2, SIGNAL(timeout()),this,SLOT(drinkNo2()));
        connect(flaskNo3, SIGNAL(timeout()),this,SLOT(drinkNo3()));
        connect(flaskNo4, SIGNAL(timeout()),this,SLOT(drinkNo4()));
        connect(flaskNo5, SIGNAL(timeout()),this,SLOT(drinkNo5()));
    
        startLoop();
    }
    
    //main.cpp
    ...
        Config config;
        config.create();
    
        KeyTranslator ktr;
        Loop loop(&config);
    ...
    

Log in to reply