Simple counter [SOLVED]



  • Hello everyone,

    How can I make a simple counter in C++ and show the numbers in qml at the same time ?
    I don't know how to start with the solution.

    Thanks in advance.



  • [quote author="Jacques" date="1353791901"]Hello everyone,

    How can I make a simple counter in C++ and show the numbers in qml at the same time ?
    I don't know how to start with the solution.

    Thanks in advance.[/quote]

    What actually do you want to do? Start counter and increment it in some period of time + display it on the QML widget?



  • Hello Tucnak

    Yes. But what bothers me is the fact that I want to have the C++ value updated on the QML in realtime. And I don't know how to do that.



  • Ok this is how it can be done:

    Suppose you have the following class that will be holding the counter--

    @
    class MyNumberHolder : public QObject
    {
    Q_OBJECT
    Q_PROPERTY( int counter READ number WRITE setNumber NOTIFY numberUpdated)
    public:
    MyNumberHolder( int value = 0 );

    public:
    int number() const;

    public slots:
    void setNumber( int value ){
    cnt = value;
    emit numberUpdated(cnt);
    }

    signals:
    void numberUpdated(int value);

    private:
    int cnt;
    };
    @

    The Q_PROPERTY defines the new variable in the Qt's meta system by setting the name of the variable (counter) and the setter/getter function through which the value will be altered/accessed. And finally the what you need the most the NOTIFY tag specifies the signal that will be fired when the variable changes.

    Next step you create an instance of the above object and register it as a property in the declarative view. For instance, in the main you can write:

    @
    QmlApplicationViewer viewer;
    MyNumberHolder numberHolder;

    viewer.rootContext()->setContextProperty("counterHolder", &numberHolder);
    @

    Now you can freely go to any of your qml file and write something like this:
    @
    ...
    Text{
    id: label
    Connections {
    target: counterHolder
    onNumberUpdated: {
    label.text = counterHolder.counter
    }
    }
    }
    ...
    @



  • Hello,
    Thanks, It works. But I have another problem. I want to make a while loop so that I don't need to click more than once. How can I manage to do that ?

    here is the code :

    @
    // Counter.h

    #ifndef COUNTER_H
    #define COUNTER_H

    #include <QObject>
    #include <iostream>

    using namespace std;

    class Counter : public QObject
    {
    Q_OBJECT

    Q_PROPERTY(float counter READ getCounter WRITE setCounter NOTIFY counterUpdated)
    

    public:
    explicit Counter(QObject *parent = 0);
    int getCounter();
    void setCounter(int);

    signals:
    void counterUpdated(int);

    public slots:
    void doTheStuff();

    private:
    int m_counter;
    };

    #endif // COUNTER_H
    @

    @
    // Counter.cpp

    #include "Counter.h"

    Counter::Counter(QObject *parent) :
    QObject(parent)
    {
    m_counter = 0;
    }
    void Counter::doTheStuff()
    {
    int c = 10;

    //while(1)    <---- this is the loop
    {
    if(m_counter < 270)
        setCounter(m_counter + c);
    else
        setCounter(0);
     }
    

    }

    int Counter::getCounter()
    {
    return m_counter;
    }

    void Counter::setCounter(int c)
    {
    cout<<"setting counter"<<endl;
    if (c != m_counter)
    {
    m_counter = c;
    emit counterUpdated(m_counter);
    }
    }

    @

    @
    //main.cpp

    #include <QApplication>
    #include "Counter.h"
    #include <QDeclarativeView>
    #include <QDeclarativeContext>

    int main(int argc, char **argv)
    {
    QApplication app(argc, argv);

    QDeclarativeView *view = new QDeclarativeView();
    Counter *c1 = new Counter();
    
    QDeclarativeContext *ctxt = view->rootContext();
    ctxt->setContextProperty("myCounter", c1);
    view->setSource(QUrl::fromLocalFile&#40;"./main.qml"&#41;&#41;;
    view->show();
    
    QObject *item = (QObject *)view->rootObject();
    QObject::connect((QObject *)item, SIGNAL(launchStuff()), c1, SLOT(doTheStuff()));
    
    return app.exec&#40;&#41;;
    

    }

    @

    @
    //main.qml

    import QtQuick 1.0

    Rectangle
    {
    signal launchStuff()

    color: "black"
    height: 300
    width:  700
    
    Image
    {
        height: 27
        width:  27
        x:100
        y:myCounter.counter
        id: name
        source: "./godbod.png"
    }
    MouseArea
    {
        anchors.fill:parent
    
        onClicked:
        {
            launchStuff()
        }
    }
    

    }
    @



  • The best way of doing what you want is through "QTimer":http://doc.qt.digia.com/qt/qtimer.html. A timer that every one second will call your function. Thus your application will not freeze there for ever so it will be responsive.

    It goes like this:

    @
    // Counter.h

    #ifndef COUNTER_H
    #define COUNTER_H

    #include <QObject>
    #include <iostream>
    #include <QTimer>

    using namespace std;

    class Counter : public QObject
    {
    Q_OBJECT

    Q_PROPERTY(float counter READ getCounter WRITE setCounter NOTIFY counterUpdated)

    public:
    explicit Counter(QObject *parent = 0);
    int getCounter();
    void setCounter(int);

    signals:
    void counterUpdated(int);

    public slots:
    void doTheStuff();

    private:
    int m_counter;
    int c;
    QTimer timer;
    };

    #endif // COUNTER_H
    @

    @
    //counter.cpp
    Counter::Counter(QObject *parent) :
    QObject(parent)
    {
    m_counter = 0;
    c = 10;
    connect(&timer, SIGNAL(timeout()), this, SLOT(doTheStuff()));
    timer->start(1000); // tick every 1 second (1000ms)
    }
    void Counter::doTheStuff()
    {
    if(m_counter < 270)
    setCounter(m_counter + c);
    else
    setCounter(0);
    }

    int Counter::getCounter()
    {
    return m_counter;
    }

    void Counter::setCounter(int c)
    {
    cout<<"setting counter"<<endl;
    if (c != m_counter)
    {
    m_counter = c;
    emit counterUpdated(m_counter);
    }
    }
    @



  • Okay.
    Thanks a lot. It's working as I want. In a way, I had to convert from while loop to if statements... considering the program as a loop. It's another way to see things :)


Log in to reply
 

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