How to use QTimer for non-ui task in QT? - c++

In my QT project I want to do a non ui activity; which is sending files to server every 60 minutes.
I tried using QTimer for it and for that QCoreApplication instance is also needed.
The timer does start and call the upload function periodically but it keeps QCoreApplication hostage (unable to delete it as timer would be running infinitely) and ultimately application crashes.
I tried to move QTimer to another thread, but that also doesn't solve the issue as app is still running in main thread.
Below is code of function which is called from __stdcall function loaded during dll initialization.
{
int argc=0;
QCoreApplication app(argc, nullptr);
QThread* newThread = new QThread(this);
QTimer *timer = new QTimer(0);
timer->setInterval(60*60*1000);
timer->moveToThread(newThread);
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(uploadFiles()), Qt::DirectConnection);
timer->connect(newThread, SIGNAL(started()), SLOT(start()));
newThread->start();
app.exec();
}
Maybe this is not best approach to do it . Need guidance on how to achieve it.
Update:
Figured out that Qtimer is definitely not ideal way to achieve it.
I was able to perform periodic execution using std::thread and atomic.

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();

Using QT events in the destructor of QApplication - hanging

I'm working with a QT GUI application which is having problems processing events during the QApplicaton destructor. A library I use (that I can't change) uses a QEventLoop. It has written some data to a socket and seems to be waiting for a response. The debugger shows that QEventDispatcherWin32::processEvents is looping and using up CPU.
I've managed to get it to work by deleting some particular widgets earlier on. However, this seems a bit random!
We are logging off our server when a widget is destroyed. Depending on what widgets are created, I sometimes get the hang and sometimes don't.
This is the exec call that hangs -
m_timedout = false;
QEventLoop loop;
QTimer timer;
timer.setSingleShot(true);
connect(&timer, SIGNAL(timeout()), this, SLOT(slt_timeout()));
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
timer.start(1800000);
connect(this, SIGNAL(sig_response(int, int, QByteArray)), &timer, SLOT(stop()));
connect(this, SIGNAL(sig_response(int, int, QByteArray)), &loop, SLOT(quit()));
loop.exec(QEventLoop::ExcludeUserInputEvents);
So what am I asking? I'm very new to QT and don't understand all the concepts but it sounds worrying to me that we are relying on QT event processing during the destructor of the application. Is that a valid thing to do? Won't QT have started to wind down?
Is there anything else that would cause that hang?

What is the proper way to execute some lambda func periodically in background thread with Qt?

I have to execute some heavy code in background thread by timeout. And I do not want to subclass QThread for every such workers. Is this a proper way?
/* inside QObject subclass */
auto thread = new QThread(this);
auto timer = new QTimer(nullptr);
timer->moveToThread(thread);
timer->setInterval(1000);
connect(timer, &QTimer::timeout, [](){
/* do lambda work */
});
connect(thread, SIGNAL(started()), timer, SLOT(start()));
connect(thread, &QThread::destroyed, timer, &QTimer::deleteLater);
thread->start();
Initially the code presented looks ok. However, it depends on what you plan to do in the lambda function and what objects you're going to use and where they reside.
Your lambda function doesn't capture any variables. If this is intended, then it should be fine. However, if you're planning on using objects which have already been instantiated on the main thread, you'll have to think carefully about their thread affinity (which thread they're running on) when you try to use them in the lambda function.
Personally, I'd create a separate object, derived from QObject, which creates the QTimer and lambda function, then move that object to the new thread. Communication between this object and those on the main thread is performed via signal and slots.

Qt how to implement a process loop?

I'm beggining with Qt and I'm currently adapting a command-line program to use it with a GUI.
I'm building my GUI like this :
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
I want to process some events permanently. In command line, I used a while loop, it work perfectly. Using Qt, I don't know how I can process these events properly.
So I tried to use a std::thread, but my Qt app crashes when I try to modify the GUI from the thread. Same problem using QThread.
I don't need threading, so it would be great if I can just put my code in the Qt's main thread.
Anyone can help me please ?
You could use a QTimer connected to a slot in your MainWindow class to run a function periodically like this :
MainWindow::MainWindow()
{
myTimer = new QTimer();
myTimer->setSingleShot(false);
myTimer->start(intervalInMilliseconds);
connect(myTimer, &QTimer::timeout, this, &MainWindow::handleMyEvents);
}
void MainWindow::handleMyEvents()
{
// Your code here
}
You could also use threads, but note that you must not call any GUI code from any thread that isn't the QApplication thread, this is probably why your attempt crashed.

QThread - problems with it (beginner)

I try to use QThread, but I can't do it :(
My sample thread:
#include "worker.h"
#include "mainwindow.h"
#include <QDebug>
Worker::Worker() {}
Worker::~Worker() {
qDebug() << "Worker ends.";
}
void Worker::run() {
qDebug() << "Worker start.";
sleep(2);
emit finished();
}
And code on_btnStart_clicked():
Worker *worker = new Worker;
QThread *workerThread = new QThread(this);
connect(workerThread, SIGNAL(started()), worker, SLOT(start()));
connect(workerThread, SIGNAL(finished()), worker, SLOT(quit()));
worker->moveToThread(workerThread);
workerThread->start();
Worker starts, but never ends (if I close application, I get QThread: Destroyed while thread is still running.
Another problem - how I can transfer data between thread and my application? I want to use QThread for QLabel (example: timer). I can't find any good tutorial that I can complile without problems.
Anyone can help me?
And, if I can ask, how I can start thread like onCreate() for form? I want to create simple timer to count time of application running.
Regards
You should have a read through This article.
Look at the first code sample of the Qt 4.8 QThread documentation. It has many lines of boiler plate just to run some code in a thread. And the there is even a leak: the QThread is never going to quit and be destroyed.
The submitted patch has been accepted but the href link he forwards you to still shows the old code.
This patch snippet diff shows the valid approach on the right-side.
It shows both methods, sub-classing QThread and using QObject->Worker
You can use that as the sample to base your code on. Apply the approach that suit's your requirements as he mentions in the blog.