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

How to show/hide qml widget from c++ like BusyIndicator



  • Hello,
    I wanted to change visible status of Busyindicator widget where I'm trying to change it from c++. Where BackEnd is my c++ class.

        BackEnd {
            id: backend
        }
        BusyIndicator {
            id: busyIndicator
            x: 1011
            y: 332
            running: backend.visibleState
            onRunningChanged: backend.visibleState = running
        }
    

    Here is my BackEnd.cpp

    void BackEnd::setUserState(bool stateSet)
    {
        state = !stateSet;
        emit userStateChanged();
    }
    bool BackEnd::visibleState()
    {
        return state;
    }
    void BackEnd::timerTimeOut()
    {
        setUserState(state);
    }
    

    Here is BackEnd.h

    class BackEnd : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(bool visibleState READ visibleState WRITE setUserState NOTIFY userStateChanged)
    
    public:
        explicit BackEnd(QObject *parent = nullptr);
    
        bool visibleState();
        void setUserState(bool stateSet);
    
    signals:
        void userStateChanged();
    
    private slots:
        void timerTimeOut();
    
    private:
        bool state = false;
        QTimer * timer1;
    };
    

    Here I can see busy indicator show/hide whenever timeout()
    But shows warning

    QML BusyIndicator: Binding loop detected for property "running"

    What is the better way to show or hide QML widget from C++

    Thanks


  • Moderators

    hi @jigarp

    this is untested, but you could try this

    BackEnd {
            id: backend
        }
        BusyIndicator {
            id: busyIndicator
            x: 1011
            y: 332
            visible: backend.visibleState
            running: visible
        }
    

    should hide the busy indicator when it's not running.



  • @J.Hilk

    This stops error but not updating widget on screen.


  • Moderators

    @jigarp what's the intervall of the timer ?

    also do you see consol logs that tell you the indicator should be changed ?

    BackEnd {
            id: backend
            onVisibleStateChanged: console.log("Indicator should be visible", visibleState)
        }
    


  • @J.Hilk

    My Timer ticks at every 1 second.

    onVisibleStateChanged: console.log("Indicator should be visible",visibleState)
    

    prints Indicator should be visible false at every 1 second


  • Moderators

    @jigarp
    very strange, your state does not change to ture. !?

    try the following

    void BackEnd::setUserState(bool stateSet)
    {
        if( stateSet != state) {
               state = stateSet;
               emit userStateChanged();
         }
    }
    
    void BackEnd::timerTimeOut()
    {
        setUserState(!visibleState());
    }
    

  • Qt Champions 2018

    @jigarp said in How to show/hide qml widget from c++ like BusyIndicator:

    running: backend.visibleState
    onRunningChanged: backend.visibleState = running

    the running: backend.visibleState line should be enough, what's the point with : onRunningChanged: backend.visibleState = running ?



  • This should work, check the following,

    In BackEnd.h:
    
    #include <QObject>
    #include <QTimer>
    #include <QDebug>
    
    class BackEnd : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(bool visibleState READ visibleState WRITE setUserState NOTIFY userStateChanged)
    
    public:
        BackEnd();
        bool visibleState();
        void setUserState(bool stateSet);
    
    signals:
        void userStateChanged();
    
    private slots:
        void timerTimeOut();
    
    private:
        bool state = false;
        QTimer * timer1;
    };
    
    

    In BackEnd.cpp, I have given interval of 1 sec (1000 msec),

    #include "BackEnd.h"
    
    BackEnd::BackEnd()
    {
        timer1 = new QTimer();
        connect(timer1,SIGNAL(timeout()),this,SLOT(timerTimeOut()));
        timer1->setInterval(1000);
        timer1->start();
    }
    
    void BackEnd::setUserState(bool stateSet)
    {
        state = !stateSet;
        qDebug()<<"Current state is "<<state;
        emit userStateChanged();
    }
    
    bool BackEnd::visibleState()
    {
        return state;
    }
    
    void BackEnd::timerTimeOut()
    {
        qDebug()<<"Timer triggered";
        setUserState(state);
    }
    
    In Qml:
        BackEnd {
           id: backend
        }
    
        BusyIndicator {
           id: busyIndicator
           width: 100
           height: 100
           x: 100
           y: 100
           running: backend.visibleState
        }
    

Log in to reply