Problem with QTimer, Signal/Slot and accessing QML text object



  • I am having issue with displaying text on the QML GUI which is printed by C++ method/slot which is run by a Signal trigerred by QTimer

    My app (MP3 player) currently does very little but here is the idea:

    • When user presses "Play" button, GStreamer starts playing MP3 file
    • Timer (QTimer) is setup for 1sec interval.
    • When timer expires it calls a method(cb_print_position ()) via Signal/Slot mechanism from the MyPlayer class which in turn produces an elapsed time in form of QString and sedns it to MyDisplay class. It also outputs the same thing to the qDebug console.
    • Output to the screen is done via MyDisplay class which I am exposing to the QML in main.cpp

    While the qDebug console shows the time stamp every second, nothing gets displayed on the QML GUI

    I did some investigation and here is what I found.
    If I call the cb_print_position () from main.cpp the time (or acutally a test string) is correctly displayed on QML GUI. If cb_print_position () is called by the Signal/Slot from within MyTimer object then nothing gets displayed. The C++ code seems to be correct (no double instances and address are passed), I am suspecting the issue is within Qt aspects or the way I used Signal/Slot mechanism.

    I will greatly appreciate some help to get me moving.

    Here is the code:
    MAIN.CPP
    @int main(int argc, char * argv[])
    {
    QApplication app(argc, argv);

    QDeclarativeView view;
    
    MyPlayer player(&view);
    MyDisplay displayTime;
    
    player.setDisplay(&displayTime);
    
    // Testing from main - works fine
    //displayTime.setText("Test");
    //player.cb_print_position();
    
    player.myGSTint();  // init GStreamer
    
    
    view.setSource(QUrl::fromLocalFile("/opt/QtPlayer3/qml/QtPlayer3/main.qml"));
    //view.setSource(QUrl::fromLocalFile("qml/QtPlayer3/main.qml"));
    view.rootContext()->setContextProperty("displayTime", &displayTime);
    view.rootContext()->setContextProperty("myQmlTest", &player);
    
    view.showFullScreen();
    view.show();
    
    return app.exec();
    

    }@
    QTPLAYER.H
    @class MyPlayer : public QObject
    {
    Q_OBJECT

    public:
    MyPlayer(QDeclarativeView * viewer);
    Q_INVOKABLE void play(const QString);
    Q_INVOKABLE void stop();
    void myGSTint();

    void mTimerInit();
    void setDisplay(MyDisplay * m_display);
    void setTimer(MyTimer * m_timer);
    

    public slots:
    void cb_print_position ();

    private:
    MyDisplay * myDisplay;
    MyTimer * myTimer;
    QString myTime;
    QString status;
    QDeclarativeView * m_viewer;
    QDeclarativeEngine * m_engine;
    QObject * object;
    QObject * songTime;
    };

    #endif // QTPLAYER_H@

    QTPLAYER.CPP - related parts only

    @MyPlayer::MyPlayer(QDeclarativeView * viewer)
    {
    myTimer = new MyTimer(this);
    qDebug() << "Timer init";
    }

    void MyPlayer::cb_print_position ()
    {
    gint64 pos, len;
    GstFormat fmt = GST_FORMAT_TIME;

    if (gst_element_query_position (pipeline, &fmt, &pos) && gst_element_query_duration (pipeline, &fmt, &len))
    {
    //g_print ("Time: %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r", GST_TIME_ARGS (pos), GST_TIME_ARGS (len));
    myTime.sprintf("Time: %u:u:u.%0u / %u:u:u\r", GST_TIME_ARGS (pos), GST_TIME_ARGS (len));
    myDisplay->setText(myTime);
    qDebug() << myDisplay->getText();
    }

    }

    void MyPlayer::setDisplay(MyDisplay * m_display)
    {
    myDisplay = m_display;
    }@

    DISPLAY.H
    @#ifndef DISPLAY_H
    #define DISPLAY_H

    class MyDisplay : public QObject
    {
    Q_OBJECT
    Q_PROPERTY(QString newText READ getText WRITE setText NOTIFY textChanged)

    public:
    // Default Constructor
    MyDisplay();

    // Overload Constructor
    MyDisplay(QString);
    
    // Accessor Funcitons
    Q_INVOKABLE QString getText() const;
    

    public slots:
    // Mutator functions
    void setText(const QString&);

    signals:
    void textChanged(QString);

    private:
    // Member variables
    QString newText;

    };

    #endif // DISPLAY_H@
    DISPLAY.CPP

    @MyDisplay::MyDisplay()
    {
    newText = "";
    }

    MyDisplay::MyDisplay(QString text)
    {
    newText = text;
    }

    QString MyDisplay::getText() const
    {
    return newText;
    }

    void MyDisplay::setText(const QString &text)
    {
    if (text != newText)
    {
    newText = text;
    emit textChanged(text);
    }
    }
    @

    MYTIMER.H

    @#ifndef MYTIMER_H
    #define MYTIMER_H
    #include <QtCore>

    class MyPlayer;

    class MyTimer : public QObject
    {
    Q_OBJECT

    public:
    MyTimer(MyPlayer * m_player);
    QTimer * mTimer;

    void StartTimer2(int mseconds);
    void StopTimer();
    MyPlayer * m_player;
    

    };

    MYTIMER.H
    @

    MYTIMER.CPP

    @MyTimer::MyTimer(MyPlayer * player)
    {
    m_player = player;
    mTimer = new QTimer(this); // "this" will cause the auto-destructor
    mTimer->setInterval(1000);
    connect(mTimer, SIGNAL(timeout()), m_player, SLOT(cb_print_position()));
    qDebug() << "\n\n*** timer initialized ***";
    }

    void MyTimer::StartTimer2(int mseconds)
    {
    mTimer->start();
    qDebug() << "\n\n*** timer started ***";
    }

    void MyTimer::StopTimer(void)
    {
    mTimer->stop();
    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.