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_OBJECTpublic:
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_Hclass 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_OBJECTpublic:
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();
}@