Qt 4.8 - How to configure signals and slots to dynamically update text on the screen in embedded device



  • Ok, so this should be a very common task. And yes there are many examples, however lot of them show separated code snippets where a beginner programmer might have issues with putting it all together.

    So the goal of this post is to hopefully get one of the experience guys show a simple code where a cpp method would be connected with a Text qml object and when the method is executed the text on the screen would be updated to new value.

    Shown below is what I have, but it does not work(the text is not being updated when setText is called). I know the text is updated because when I run getText() and output it to console the new value is printed.

    I have a feeling it is because I have not used the "connect" statement, but i am not sure which two objects I should connect and also what is the slot name in the QML section for the Text object to connect to.

    display.h
    @#include <QObject>
    #include <QtDeclarative>

    #ifndef DISPLAY_H
    #define DISPLAY_H

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

    public:
    // Default Constructor
    Display();

    // Overload Constructor
    Display(QString);
    
    // Accessor Funcitons
    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
    @#include "display.h"

    Display::Display()
    {
    newText = "";
    }

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

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

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

    main.cpp
    @int main(int argc, char * argv[])
    {
    QScopedPointer<QApplication> app(createApplication(argc, argv));
    QmlApplicationViewer viewer;

    Display displayTime;
    
    viewer.rootContext()->setContextProperty("displayTime", &displayTime);
    
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    
    viewer.setMainQmlFile&#40;QLatin1String("qml/QtPlayer3/main.qml"&#41;&#41;;
    
    viewer.showExpanded();
    viewer.showFullScreen();
    
    return app->exec(&#41;;
    

    }@

    main.qml - this is only the small section showing the text object
    @ Text
    {
    id: time
    //text: "none"
    color: "#999999"
    font.pixelSize: 30
    anchors.topMargin: 90
    anchors.top: parent.top
    anchors.horizontalCenter: parent.horizontalCenter
    text: displayTime.getText
    }@



  • Can you show the code where you change displayTime text? I tested on my pc and it seems to work fine.



  • Good point and sorry for missing this. Here is the function which gets called by a timer every second. For simplicity I just output a "XXXX" string. The goal is to have the GStreamer output the timestamp but that should be easy once I get this going.
    When this code is executed the "XXXX" is printed every second in the Debug window, but the QML text object "time" stays blank.

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

    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 = GST_TIME_ARGS (pos);
    newTime.setText("XXXX");
    qDebug() << newTime.getText();

    }

    }@



  • I'm asking the obvious questions first:

    Display newTime in void MyPlayer::cb_print_position (), is this the same object as you expose in the main.cpp?



  • Please excuse my terminology and if I make stupid errors (beginner in C++)

    Well it is the same object but obviously different instance. I think this is the problem. But how can make it the same instance?



  • Object and instance are synonyms. They are both from the Display class.

    The function @viewer.rootContext()->setContextProperty("displayTime", &displayTime); @ lets you use in QML the instance *displayTime *you created in the main function. So only displayTime can be used in your QML files.

    How you pass this object to the right functions depends on your program and there is no one way to do this.

    I would like to stress the following though, the @newTime@ you create in the function @void MyPlayer::cb_print_position ()@ is created each time you call; it and will cease to exist the moment the function is finished. If this is new information for you, I suggest you first look deeper into C++ first, before starting using Qt.



  • No worries, it is not new concept for me but, I still make these obvious errors and have trouble with the high level C++ program architecture.

    Thx for your time and for leading me in the right direction. It looks like I got some C++ reading ahead of me ;-).


Log in to reply
 

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