i am getting QObject::startTimer: Timers cannot be started from another thread from this snippet and it's blocking my application and freezing the UI. I am kind of new to threading in QT.
void ReportModel::myslot(){
moveToThread(&thread);
connect(&thread, SIGNAL(started()), this, SLOT(exportProg()));
thread.start();
}
in exportProg() i am making a csv file in pendrive.
Given that ReportModel is likely a class used from the GUI thread, this won't work and is a bad idea. this->moveToThread(...) is usually a bad code smell unless you know exactly what you're doing.
Why are you moving the model to a thread in a slot? Shouldn't it be in a thread from the very beginning? Why are you connecting slots to the started signal? The idiom for job submittal to the current object thread's event loop can be QTimer::singleShot(0, ...) or QMetaObject::invoke, and that works without any dependency on a thread starting at that very moment. Most likely, exportProg should be a threadsafe method that can be submitted for asynchronous execution via QtConcurrent::run.
Related
I have an QThread which listen server. I want to pause work of QThread immediately. Not waiting at all, but almost like terminating, it must be immediate.
A code running in any given thread cannot be stopped at an arbitrary point without corrupting the state of the shared data structures in your code and/or the C/C++ runtime or any other libraries that are used.
The code can only stop at well-defined points.
If your thread runs an event loop (i.e. usually if you don't derive from QThread or don't override its run), then QThread::quit() will stop the thread once it returns control to the event loop, where it's safe to do so.
If your thread reimplements run and executes a loop there, it should return when interruption is requested:
void MyThread::run() {
while (! isInterruptionRequested()) {
...
}
}
Such a thread is stoppable by QThread::requestInterruption().
For reference, here are various methods of QThread that are sometimes confused:
wait() blocks the calling thread until the called thread finishes. Of course, calling it from within the thread itself is instant deadlock: a thread can't finish if it waits for something that's never going to happen.
quit() quits the thread's event loop at the earliest opportunity, and causes QThread::run() to return. It does nothing if you're reimplemented run() and don't spin an event loop.
requestTermination() sets a flag that a custom loop in YourThread::run() can check via isTerminationRequested().
terminate() stops the thread now. This generally corrupts the state of your application, so you must abort() sometime soon or face the consequences. This method is best forgotten about. It essentially means "crash this process soon and corrupt some disk data if you get a chance".
I've read there are two approaches for working with QThread.
If I have a Worker class, which inherits QObject (as in http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/), then how should I create and manage local QEventLoop for working with signals/slots? I don't want to have memory leaks.
How QNetworkAccessManager should be created in worker described in http://codethis.wordpress.com/2011/04/04/using-qthread-without-subclassing/?
If you don't subclass QThread, it has its own event loop (Fixed QThread documentation of Qt 5, also appliccable for Qt 4):
By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.
Managing the work done by the worker can be easily done using signals & slots:
(...) you are free to connect the Worker's slots to any signal, from any object, in any thread. It is safe to connect signals and slots across different threads, thanks to a mechanism called queued connections.
This means you usually don't need to care about any event loop on your own (unless you require special behaviour). Simply connect the thread's started signal to any slot of your worker object and make sure you set up some kind of deletion chain: Either the worker emits a signal which leads to the thread being stopped and deleted, or the other way round - both ways work, depending on your situation.
I'm an advanced beginner using Qt and I'm trying to write a console app that uses QFtp. The app itself is essentially just procedural code but because QFtp is asynchronous this is driving me crazy. I need to test that multiple ftp downloads are successful, but the code doesn't block so the test always fails. The best solution so far is to create a chain of signals and slots daisy chaining the ftp code and the procedural sections. It seems there has to be a better way. Any ideas?
You can use QEventLoop to wait for a signal. Just connnect the signal to QEventLoop::quit(), and then call QEventLoop::exec().
QFtp ftp;
QEventLoop eventLoop;
connect(&ftp, SIGNAL(commandFinished(int,bool)), &eventLoop, SLOT(quit()));
eventLoop.exec();
As it's asynchronous you're best off tracking it through the signal and slots mechanism, but that does throw off your procedural logic. The only other default option for FTP in Qt is QNetworkAccessManager but that's also asynchronous, so whichever you go for you're going to have to use the signal/slots system to track when it's done.
You could use QTcpSocket and write your own FTP code, that allows you to block the calling thread until it returns with certain conditions, but you'll have to write significantly more code to do what you want to.
I was digging into some source code I am working on. I found a peculiar statement that someone had coded. The source code is a GUI application with a QML GUI and uses QT 4.7.x.
The snippet below belongs to core application logic.
// connect signal-slots for decoupling
QObject::connect (this, SIGNAL(setCurrentTaskSignal(int)), this,
SLOT(SetCurrentTaskSlot(int)), Qt::QueuedConnection);
It's strange that the object connects to itself via a queued connection which essentially means that the object may "live" in different threads at the same time?
At first glance It didn't made any sense to me. Can anyone think of any reason why such a connection would be plausible or needed?. Would this even work?
It will work without any problem. Maybe there was some event loop processing required before calling SetCurrentTaskSlot?
Note that QueuedConnection doesn't mean that something is in different thread. QueuedConnection means only that when signal is emitted, corresponding slot won't be called directly. It will be queued on event loop, and will be processed when control will be given back to event loop
The queued connection implies nothing about where the receiver lives. The opposite is true: to safely send signals to an object living in another thread, you must use queued connections. But you can use them for an object living in any thread!
One uses a queued connection to ensure that the signal will be delivered from within the event loop, and not immediately from the emit site as happens with direct connection. Direct connection is conceptually a set of calls to function pointers on a list. Queued connection is conceptually an event sent to a clever receiver who can execute a function call based on the contents of the event.
The event is the internal QMetaCallEvent, and it is QObject::event that acts upon this event and executes the call.
I am trying to use Qt as a library (similar to this), because I want to reuse Qt classes in some currently non-Qt applications, and in shared libraries as cross-platform glue. Everything is non-GUI.
Some problems are easily avoided by DirectConnection, some can be solved with private event loops, even one can run a fake QCoreApplication in a thread and it works (last resort).
I want to know what modules rely on a running instance of QCoreApplication and cannot work without it.
Some of the Qt modules (in QtCore) do need an instance of QCoreApplication to run properly. For example QTimer relies on QCoreApplication to dispatch timer events.
I was reading the documentation for QtConcurrentRun and it seems to be relying on a global instance of QThreadPool, I am about to try and see if the application execution is vital, or maybe the instance is created on first access, or maybe not.
I am going to study QCoreApplicationPrivate source (Windows and Linux for now) but any hints in the right direction is greatly appreciated.
What are other functionality dependencies to the core application? Note that it might depend on the OS.
Edit1: Thanks to Kuba's answer, It seems QCoreApplication event loop is not necessary for timer and socket events to be dispatched. So some QtCore modules require and instance of QCoreApplication, but there is no need to have a running application event loop.
You are conflating the existence of a QCoreApplication with a running event loop. Those two are separate concepts. You may well need the former for the latter, but the latter doesn't have to run in the same thread as the former.
Most notably, you don't really have to call qApp->exec() if you don't have any events to dispatch in the thread where you constructed QCoreApplication.
The existence of a QCoreApplication is, as it were, a non-issue. Things get hairier with QApplication -- you can start it in a non-gui thread, but it's not portable and won't work on OS X. I'm trying to figure out why it doesn't work, but I don't have much time now to offer a satisfactory solution -- not yet.
It is also a misconception that QCoreApplication's event loop needs to be running for socket notifications and timer events to be dispatched to other threads. A QCoreApplication's event loop is nothing special. There is a platform-specific instance of QAbstractEventDispatcher that gets created for a thread when you instantiate the first QEventLoop in that thread. The QEventLoop doesn't know anything specific about the platform.
QCoreApplication's exec() method is quite simple and creates an instance of QEventLoop, and thus will create an instance of platform-specific QAbstractEventDispatcher. This instance is not special in any way. It's the same as any other event dispatcher created in any other thread, as far as my code reading tells so far.
If all underlying window systems would support it, it'd be in fact possible to make Qt GUI code multithreaded -- the per-thread event reception and dispatch is already there as a small first step. The big obstacle, probably the only one, would be the X library and its display lock. The display lock would be an obvious matter of contention between threads. You'd need each thread that wants to talk to the GUI open up a separate connection to the X server, and I don't know if there's a supported way of doing that from Xlib.