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

How to conditionally disable QML Binding to C++ backend?



  • I am working on QML Application for an embedded system that has a lot of property bindings: many sensor data is displayed throughout different pages of the app. Only 1 page is visible at a time.

    When I'm on page 2, the property bindings for page 1 are still taking place, even though visible is set to false on page 1. I wish to have QML respond to binding updates, only when the page is visible, as it would improve performance.

    I have tried using the Binding element as described here: Binding QML Type and here: https://stackoverflow.com/questions/32506359/prevent-qml-property-bindings-when-qml-object-isnt-visible?rq=1, but I've noticed that a binding will still update in QML.

    I am wondering if it is possible to completely eliminate the binding, if not on page 1.

    My code for my attempt at using the Binding Element is attached below. Instead of multiple pages being visible/invisible, I've used a button that toggles a activated property.

    main.qml

    Rectangle{                                                                               
        x: 280                                                                                         
        y: 20                                                                                          
        width:200                                                                                      
        height:150                                                                                     
        color:"red"                                                                                             
        Text {                                        
            y: 76                                                                                      
            width: 85                                                                                  
            height: 67                                                                                 
            text: "off"                                                  
            Binding on text {                                               
                value: {                                                                               
                    // I am surprised to find this prints, regardless of value of controlRect.activated       
                    console.log("new value");                                                          
                    sensorData.sensorReading.toFixed(1)                                                
                }                                                                                      
                when: controlRect.activated                                                            
            }                                                                                          
        }                                                                                              
    }                                                                                                  
                                                                                                       
    Rectangle{                                                                                         
        id: controlRect                                                                                
        x: 20                                                                                          
        y: 20                                                                                          
        width:200                                                                                      
        height:150                                                                                     
        property bool activated: true                                                                  
        color:{                                                                                        
            if (controlRect.activated){                                                                
                "green"                                                                                
            }                                                                                          
            else{                                                                                      
                "yellow"                                                                               
            }                                                                                          
        }                                                                                              
                                                                                                       
        MouseArea {                                                                                    
            anchors.fill: parent                                                                       
            onClicked: {                                                                               
                console.log("State changed to",!parent.activated);                                     
                parent.activated = !parent.activated                                                   
            }                                                                                          
        }                                                                                         
    }                                                                                                  
    

    backend.cpp, instantiated in main.cpp

    #include "backend.h"
    #include <QQmlContext>
    
    Backend::Backend(QQmlApplicationEngine* engine, QObject *parent) :
        QObject(parent)
    {
        sensorData = new SensorData();
         QQmlContext* ctxt(engine->rootContext());
    
        // Connecting back end object instances to front end
        ctxt->setContextProperty("sensorData", sensorData);
    }
    

    sensordata.h

    #ifndef SENSORDATA_H
    #define SENSORDATA_H
    #include <QObject>
    #include <QTimer>
    
    class SensorData : public QObject
    {
        Q_OBJECT
    public:
        Q_PROPERTY(double sensorReading MEMBER m_sensorReading NOTIFY sensorReadingChanged)
    
        explicit SensorData(QObject *parent = nullptr);
        ~SensorData() {}
    
    private:
        double m_sensorReading;
        double temp;
        QTimer m_timer;
    
    signals:
        void sensorReadingChanged();
    
    public slots:
        void slot_updateReading();
    
    };
    
    #endif // SENSORDATA_H
    

    sensordata.cpp

    #include "sensordata.h"
    #include <QDebug>
    
    SensorData::SensorData(QObject *parent) :
        QObject(parent)
    {
        // for simulating sensor data
        srand( (unsigned)time(NULL) );
        m_timer.setInterval(100);
        m_timer.setSingleShot(false);
        QObject::connect(&m_timer, &QTimer::timeout, this, &SensorData::slot_updateReading);
        m_timer.start();
    }
    
    // simulate my sensor data
    void SensorData::slot_updateReading(){
        m_sensorReading = modf(rand() /  100000.0, &temp);
        emit sensorReadingChanged(); // emit for QML binding to update
    }
    

  • Moderators

    @HiddenNetwork
    in all honesty, the best/proper way would be by using a Loader component to only load those files that you actually need/want to show.

    That would take care of the binding issue and increase even more the performance.


Log in to reply