Call a function n times with an interval of n seconds - c++

I want to simply call a function 4 times within an interval of 10 seconds.
This calls it only once
QTimer *timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, SIGNAL(timeout()), this, SLOT(myFunction()));
timer->start(10000);
And if I get rid of the setSingleShot method, it will be called forever. Is there a built in way to call it only n times. I couldn't find it in the Qt documentation.

The brute-force, non-scalable way: start four timers.
A more practical way is to have the callback keep track of how many times it has been called, then stop the timer on the fourth call.

Related

QTimer dont stop when windows is closed

I am currently starting on QTCreator. I have been asked to use QTimers in a particular context which is this:
We have an open window,
One or more QTimers are triggered and make things appear on the screen every x msec.
When we press "Escape" the window should close and everything should be reset to 0.
But here is the problem, the timers are defined in a static way:
QTimer::singleShot(500, this, SLOT(foo());
When I call this->close() (which closes my window), the timers do not stop and continue. I tried several solutions: browse all the QTimers contained in my object, obviously there are none since they are defined in static. Instead of declaring them in static I've tried to create each time a new QTimer object like that:
QTimer *timer= new QTimer(this);
timer->setSingleShot(true);
timer->setInterval(2000);
timer->setParent(this);
timer->start();
And then call timer->stop() later, but I think it's very brutal when you have multiple Timers in the same code.
Is there a way to stop the timers when this->close is called, knowing that the timers are defined as a static one ?
Assuming you are using,
QWindow *qw = new QWindow();
QTimer *timer= new QTimer();
To solve the issue you need to connect destroyed() signal of QWindow to timer's slot stop()
So as soon as window is destroyed all registered timers will be stopped without explicit stop call. make sure you connect all timer instances. Code snippet as following,
QObject::connect(&qw, SIGNAL(destroyed()), timer, SLOT(stop()))
QObject::connect(&qw, SIGNAL(destroyed()), timer2, SLOT(stop()))
QObject::connect(&qw, SIGNAL(destroyed()), timer3, SLOT(stop()))
PS:
QTimer *timer= new QTimer(this); // here you are setting parent as 'this' already
timer->setSingleShot(true);
timer->setInterval(2000);
timer->setParent(this); // remove this, no need to set parent again.
timer->start();

How to properly using infinite loop in Qt GUI?

I am new to and learning the Qt GUI framework.
I have an ultrasonic sensor wired up to the Raspberry Pi, to measure water level. If I were coding in C, I would have used a while(1) loop to constantly read the sensor input. But when I put while(1) inside MainWindow.cpp, the window cannot be displayed. However, using qDebug() I can still print out the sensor value, which means my while(1) still running but the main window won't appear. I found out in this answer that because of while(1),
MainWindow ctor never returns, so w.show() is never called and a.exec() (main message loop) is never executed.
To solve this, I use QTimer instead of a loop: connect the timeout() SIGNAL to a SLOT which is a function to read the sensor value one-time:
waterLevelTimer = new QTimer(this);
connect(waterLevelTimer, SIGNAL(timeout()), this, SLOT(getWaterLevel()));
waterLevelTimer->start(100); // "loop" once every 100 millisecond
With this method, I can read the sensor value with the fastest interval is 1 millisecond and the GUI still displayed fine.
But should I use QTimer to mimic a while(1) loop? Is there a better way to have an infinite loop to read GPIOs while still being able to use GUI for other work?
The main thread where the GUI of Qt runs never should be blocked by long-lasting operations like an infinite while-loop, because otherwise you would block the event system and nothing will work anymore.
Instead you usually create a worker thread in parallel (see QThread) where you do your loop in the run function of the thread. Maybe also use such timer as you suggest, which works if the executed code is faster than the timer duration.
QThread *thread = QThread::create([]{
while(1)
checkSomething();
});
thread->start();

Adding a timer to a qt application

I'm attempting to build a program which takes any text file and turns it into a typing test. It has a timer that will display to the screen.
However, I can't figure out how to display the timer while actually running my game instructions. The timer works and displays the elapsed time but displaying the timer is the only thing it will do.
Can anyone give me some pointers of things that might be helpful for solving this problem?
QTimer has a signal timeout() which will be emitted after your interval time is elapsed. A QTimer unless specified as a singleshot runs again and again.
Let's assume you wish to do something every second, you can start a timer with interval 1000 (in msec). You can then connect its timeout signal to a slot. There you can specify how to go about doing stuff.
It's fine to run multiple timers at the same time. Also, for your initial implementation (for displaying the timer); you might want to take a look at QElapsedTimer.
Edit:
I found this example. It might provide you something to look at.
QTimer emits timeout() signal in every time interval specified by you unless it's a 'single-shot' timer.
If you want to display the elapsed time, connect the timeout() signal of your timer object to your slot which will display the time elapsed. Your slot will contain your logic to display whatever you want.

How to call a function periodically in Qt?

Is it possible to call a function periodically in C++ with Qt function ?
And how to stop the timed function after it is set to be called periodically ?
If you are using qt, you can you QTimer which by default creates a repetitive timer.
There is an example in the documentation (shown below) and an example (Analog Clock).
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
One possibility would be to use a QTimer timeout signal and a QObject slot. Connect the two and start() the timer.
http://qt-project.org/doc/qt-4.8/qtimer.html#timeout
To stop the timer, call stop().
As people have said in answers before me, you can use the timeout() signal to trigger a function to run.
If you want to stop the timer at some point, you can connect to the stop() slot, or call it directly yourself.
You can use the QTimer class.
Just declare a QTimer with the desired time interval, wrap your function in a QObject as a slot, and connect the QTimer's timeout() signal to the slot you just declared.
Then, when the condition for stopping calling the function is met, just call QTimer::stop().
Make a function that uses timer functionallity or a while loop that just waits for 100 ms and when your function meets the requirement just break. You could quite easy found a solution on this one if you just made a search among all the other questions that has been posted here.

QT progress bar speed

Does QT provide any functions to control a progress bar's speed? For example, if I want it to increase by 1% every 1 second, is there any QT way to do it instead of using a loop and sleeping for 1 second between each value change?
You can use QTimeLine for this. The detailed description in the documentation gives an example of exactly what you want.
Use a QTimer.
Connect the signal timeout() to a slot that increases the value in the QProgressBar.
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
In this cas, update() will be call each second.
If you're using Qt 4.6 you can also use QPropertyAnimation