Not able to receive signal emitted from QTimer elapsed callback
I have a QTimer which times out every 3 seconds. In the slot for the timeout I emit a signal. I intend to catch this signal in QML. Unfortunately this fails. 
If I try for example to emit the signal in a Q_PROPERTY READ function, then I'm able to receive the signal in QML. 
I suspect the failure here is due to the context in which QTimer's timeout slot runs. But I'm unable to figure out the reason. 
Below is the code:

    class Seeker: public QObject
    {
        Q_OBJECT
        Q_PROPERTY(qreal seekPercent READ seekPercent NOTIFY seekPercentChanged)
        Q_PROPERTY(QString source READ source NOTIFY sourceChanged)
    //--------------------------------------------------------------------
    // Construction & Destruction
    public:
        Seeker();
    
        virtual ~Seeker();
        QString source() { emit sourceChanged(); return "test";}
    
    signals:
        void seekPercentChanged();
        void sourceChanged();
    //--------------------------------------------------------------------
    // Functions
    public Q_SLOTS:
    
        void registerSeekUpdater(SeekSink* pClient/*,const pfnSeekUpdate pfn*/);
        virtual void TickElapsed();
        virtual qreal seekPercent() const; 
        void seekUpdate(const bool enableUpdate);
        double getSeekPositionPercent() const;
    
    
    //--------------------------------------------------------------------
    // Data
    private:
        int m_TotalDuration;
        int m_CurrentDuration;
        double m_seekPercent;
        QTimer* m_Timer;
        SeekSink* m_client;
    
    };
    
    
    Seeker::Seeker(/*QObject* parent*/)/*:QObject(parent)*/
    {
        m_TotalDuration = 0;
        m_CurrentDuration = 0;
        m_seekPercent = 0.0;       
        m_client = NULL;
        m_Timer = new QTimer(this);
        connect(m_Timer, SIGNAL(timeout()), SLOT(TickElapsed()));
        m_Timer->setSingleShot(FALSE);
    }
    //--------------------------------------------------------------------
    //
    Seeker::~Seeker()
    {
        m_TotalDuration = 0;
        m_CurrentDuration = 0;
        m_seekPercent = 0.0;
        //m_pfn = NULL;
        m_client = NULL;
        //m_parent = NULL;
        if(NULL!= m_Timer)
        {
            delete m_Timer;
            m_Timer = NULL;
        }
    }
    
    //--------------------------------------------------------------------
    //
    void Seeker::registerSeekUpdater(SeekSink* pClient)
    {
        if(pClient != NULL)
        {
            m_client = pClient;
        }
        else
        {
            qDebug()<< "No callback func registered";
        }
    }
    //--------------------------------------------------------------------
    //
    void Seeker::TickElapsed()
    {
        //Ask the current and total duration from the client thru callback
        if(/*m_pfn != NULL && */m_client != NULL)
        {
            m_client->/*(*m_pfn)*/SeekUpdater(&m_CurrentDuration,&m_TotalDuration);
        }
        //emit seekPositionChanged(/*getSeekPositionPercent()*/);
        m_seekPercent = getSeekPositionPercent();
        emit seekPercentChanged();
        qDebug() << "seekPositionChanged" <<getSeekPositionPercent();
    
    }
    
    //--------------------------------------------------------------------
    //
    void Seeker::seekUpdate(bool enableUpdate)
    {
        if(m_Timer)
        {
            if(enableUpdate)
            {
                m_Timer->start(SEEKBAR_UPDATE_FREQUENCY);
            }
            else
            {
                m_Timer->stop();
            }
        }
    }
    
    //--------------------------------------------------------------------
    //
    double Seeker::getSeekPositionPercent() const
    {
        if(m_TotalDuration == 0)
        {
            qDebug() << "Invalid duration.. Cannot compute seek percentage";
            return 0.0;
        }
        else
        {
            return ((double)m_CurrentDuration/m_TotalDuration);
        }
    }
    //--------------------------------------------------------------------
    //
    qreal Seeker::seekPercent() const
    {
       return (qreal)m_seekPercent;
    }


QML

    Rectangle {
        id: player
        width: 968
        height: 480
        color: "lightblue"
        anchors.fill: parent
    
        Rectangle {
            id: seekbar
            width:parent.width -20
            height:12
            opacity: 0.5
            color: "yellow"
            border.color: "black"
            border.width: 1
            x:10
            y:400
            Component.onCompleted: {
                console.log("completed rect1")
    
            }
        }
    
        Rectangle {
            id: cursor
            width:5
            height:18
            color: "black"
            anchors.horizontalCenter: seekbar.left
            anchors.verticalCenter: seekbar.verticalCenter
            property double intseekPercent: 0.0
    
            states: State {
                name: "moved"
                PropertyChanges { target: cursor; x: seekbar.width * intseekPercent }
            }
    
            transitions: Transition {
                PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
            }
    
            Component.onCompleted: {
                console.log("completed rect2")
    
            }
    
            }
    
            Connections {
                target: runtime.seeker
                onSeekPercentChanged: {
                           console.log("onSeekPositionChanged");
            //               intseekPercent = seekPercent;
            //               signal.state = "moved"
                       }
            }
            Connections {
                target: runtime.seeker
                onSourceChanged: {
                           console.log("onSourceChanged");
            //               intseekPercent = seekPercent;
            //               signal.state = "moved"
                       }
            }
    
    
    
    
    
        Component.onCompleted: {
            console.log("completed rect0")
            console.log(runtime.seeker.source)
    
        }
    }

Of course I have a main.cpp which loads the QML document
So the problem I'm facing is that though the signal sekPercentChanged gets emitted, I'm not able to receive it in QML. Whereas the dummy signal sourcetChanged is being received successfully when the read function source() gets called via QML.
Not able to receive signal emitted from QTimer elapsed callback
===

I have a QTimer which times out every 3 seconds. In the slot for the timeout I emit a signal. I intend to catch this signal in QML. Unfortunately this fails. 
If I try for example to emit the signal in a Q_PROPERTY READ function, then I'm able to receive the signal in QML. 
I suspect the failure here is due to the context in which QTimer's timeout slot runs. But I'm unable to figure out the reason. 
Below is the code:

    class Seeker: public QObject
    {
        Q_OBJECT
        Q_PROPERTY(qreal seekPercent READ seekPercent NOTIFY seekPercentChanged)
        Q_PROPERTY(QString source READ source NOTIFY sourceChanged)
    //--------------------------------------------------------------------
    // Construction & Destruction
    public:
        Seeker();
    
        virtual ~Seeker();
        QString source() { emit sourceChanged(); return "test";}
    
    signals:
        void seekPercentChanged();
        void sourceChanged();
    //--------------------------------------------------------------------
    // Functions
    public Q_SLOTS:
    
        void registerSeekUpdater(SeekSink* pClient/*,const pfnSeekUpdate pfn*/);
        virtual void TickElapsed();
        virtual qreal seekPercent() const; 
        void seekUpdate(const bool enableUpdate);
        double getSeekPositionPercent() const;
    
    
    //--------------------------------------------------------------------
    // Data
    private:
        int m_TotalDuration;
        int m_CurrentDuration;
        double m_seekPercent;
        QTimer* m_Timer;
        SeekSink* m_client;
    
    };
    
    
    Seeker::Seeker(/*QObject* parent*/)/*:QObject(parent)*/
    {
        m_TotalDuration = 0;
        m_CurrentDuration = 0;
        m_seekPercent = 0.0;       
        m_client = NULL;
        m_Timer = new QTimer(this);
        connect(m_Timer, SIGNAL(timeout()), SLOT(TickElapsed()));
        m_Timer->setSingleShot(FALSE);
    }
    //--------------------------------------------------------------------
    //
    Seeker::~Seeker()
    {
        m_TotalDuration = 0;
        m_CurrentDuration = 0;
        m_seekPercent = 0.0;
        //m_pfn = NULL;
        m_client = NULL;
        //m_parent = NULL;
        if(NULL!= m_Timer)
        {
            delete m_Timer;
            m_Timer = NULL;
        }
    }
    
    //--------------------------------------------------------------------
    //
    void Seeker::registerSeekUpdater(SeekSink* pClient)
    {
        if(pClient != NULL)
        {
            m_client = pClient;
        }
        else
        {
            qDebug()<< "No callback func registered";
        }
    }
    //--------------------------------------------------------------------
    //
    void Seeker::TickElapsed()
    {
        //Ask the current and total duration from the client thru callback
        if(/*m_pfn != NULL && */m_client != NULL)
        {
            m_client->/*(*m_pfn)*/SeekUpdater(&m_CurrentDuration,&m_TotalDuration);
        }
        //emit seekPositionChanged(/*getSeekPositionPercent()*/);
        m_seekPercent = getSeekPositionPercent();
        emit seekPercentChanged();
        qDebug() << "seekPositionChanged" <<getSeekPositionPercent();
    
    }
    
    //--------------------------------------------------------------------
    //
    void Seeker::seekUpdate(bool enableUpdate)
    {
        if(m_Timer)
        {
            if(enableUpdate)
            {
                m_Timer->start(SEEKBAR_UPDATE_FREQUENCY);
            }
            else
            {
                m_Timer->stop();
            }
        }
    }
    
    //--------------------------------------------------------------------
    //
    double Seeker::getSeekPositionPercent() const
    {
        if(m_TotalDuration == 0)
        {
            qDebug() << "Invalid duration.. Cannot compute seek percentage";
            return 0.0;
        }
        else
        {
            return ((double)m_CurrentDuration/m_TotalDuration);
        }
    }
    //--------------------------------------------------------------------
    //
    qreal Seeker::seekPercent() const
    {
       return (qreal)m_seekPercent;
    }


QML

    Rectangle {
        id: player
        width: 968
        height: 480
        color: "lightblue"
        anchors.fill: parent
    
        Rectangle {
            id: seekbar
            width:parent.width -20
            height:12
            opacity: 0.5
            color: "yellow"
            border.color: "black"
            border.width: 1
            x:10
            y:400
            Component.onCompleted: {
                console.log("completed rect1")
    
            }
        }
    
        Rectangle {
            id: cursor
            width:5
            height:18
            color: "black"
            anchors.horizontalCenter: seekbar.left
            anchors.verticalCenter: seekbar.verticalCenter
            property double intseekPercent: 0.0
    
            states: State {
                name: "moved"
                PropertyChanges { target: cursor; x: seekbar.width * intseekPercent }
            }
    
            transitions: Transition {
                PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
            }
    
            Component.onCompleted: {
                console.log("completed rect2")
    
            }
    
            }
    
            Connections {
                target: runtime.seeker
                onSeekPercentChanged: {
                           console.log("onSeekPositionChanged");
            //               intseekPercent = seekPercent;
            //               signal.state = "moved"
                       }
            }
            Connections {
                target: runtime.seeker
                onSourceChanged: {
                           console.log("onSourceChanged");
            //               intseekPercent = seekPercent;
            //               signal.state = "moved"
                       }
            }
    
    
    
    
    
        Component.onCompleted: {
            console.log("completed rect0")
            console.log(runtime.seeker.source)
    
        }
    }

Of course I have a main.cpp which loads the QML document
So the problem I'm facing is that though the signal sekPercentChanged gets emitted, I'm not able to receive it in QML. Whereas the dummy signal sourcetChanged is being received successfully when the read function source() gets called via QML.