how is the connection between signal and slot made in QT? - qt

I have been a Qt programmer for quite some time now and i understand most of the general features of Qt. I am still confused about how the connect statement connects a signals to a slot at run time. Basically i would like to understand what happens at compile time and what happens at run time..
compile time: meta object compiler will generate code to implement a signal in an additional cpp file (one for each class containing Q_OBJECT).
run time: signal is mapped to a slot, slot gets executed? this is the part i am not clear about...SIGNAL and SLOTS are macros that expand to string representation of the signal/slot names...how does this and the meta object help in mapping calls to slots at run time? details would be appreciated...
EDIT:
this link will give you a better idea..(only if you are interested in the gory details...)
http://dev.libqxt.org/libqxt/wiki/Meta_Object_Format
couple this with the documentation of QMetaObject and things should become clear...

There are various ways you can connect a signal to a method (signal/slot).
However, they all revolve around getting the correct method number.
After you have the correct method number and the object to call it on, you simply call a virtualized function (qt_metacall) in QObject which finds the correct method to call from the number given. You can find this function in the files that the MOC generates. Also, in that generated file, you can find a line which creates a static QMetaObject of your class. This object registers the names of your slots and signals to the method numbers.
These might provide some interesting stuff to read:
http://doc.qt.io/qt-5/qmetaobject.html
http://doc.qt.io/qt-5/metaobjects.html
http://doc.qt.io/qt-5/signalsandslots.html
You can also learn a lot by running thought the slot activations with a debugger.

Basically signals and slots work similar to messages in Objective-C.
The macros cause the preprocessor to replace them with some code which "registers" and "looks up" the functions/methods that are to be effectively executed when a slot is called.
This allows for more flexibility, because the code that is emitting a signal or calling a slot does not need to know much about the other code modules which use them. Each slot and signal generate a signature that is looked up at runtime and then called.
If you are familiar with C/C++, you can compare this to dynamic libraries. Symbols are looked up at runtime and their address is then used to let the CPU "jump" to them to execute.
Also, these links might help you:
Qt question: How do signals and slots work?
http://doc.qt.io/qt-5/signalsandslots.html

Related

Passing object via Qt signal/slot across threads

I wish to pass an object using the signal/slot mechanism between threads in Qt. Since I will be passing a pointer to the object, is it safe to call the methods on the object on the receiver's side?
According to this question question the object is not copied (so using original object).
Is this safe? Or am I executing methods on an object belonging to one thread in another thread? Is there a better way to do this?
(I have approximately 20 getters in this class so I don't want to pass individual variables, as well some of the variables are in fact pointers to objects as well)
It is not necessarily safe - signals and slots can be used to cross thread boundaries, so it's possible you could end up trying to access the object from another thread.
The thread in which the slot will be called is determined by the connection type. See the documentation, but as an example:
connect(source, SIGNAL(mySignal(QObject*)), destination, SLOT(mySlot(QObject*)), Qt::DirectConnection);
In this case the function mySlot() will be called from the same thread that the mySignal() signal was emitted in. If your object is not accessed from any threads other than the same thread as the signal emitter this would work fine.
connect(source, SIGNAL(mySignal(QObject*)), destination, SLOT(mySlot(QObject*)), Qt::QueuedConnection);
In this case the function mySlot() will be queued, and called by the event loop of the destination object. So anything done to the object, would happen from within the thread running the event loop of the destination.
I personally find it's best to just stick to passing simple values as arguments. Even though this can work, you would need to add suitable multithreading guards to your QObject if it's likely to be accessed from multiple threads.
First of all, try to use QtConcurrent when you are developing a multi-threaded application. The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded programs without using low-level threading primitives such as mutexes, read-write locks, wait conditions, or semaphores.
After that, safety depends on your class members. If all members are thread-safe, then all will be run safely.

Whats the difference between a normal function and a slot in Qt?

Whats the difference between a normal function and a slot in Qt? I have read that slots are like normal functions but in addition can be connected to signals, but normal functions can just as well.
The difference is that slots with get MOC treatment and generate meta data, which is required for certain Qt functionality that involves runtime lookup by member names passed as strings.
For connections alone, plain member functions are perfectly OK since Qt 5 using the new connection syntax.
For Qt 4 you have no option but to use slots.

Blocked QFuture.result() or QFutureWatcher.waitForFinished();

So I have been using QtConcurrent::run for some time and its fantastic. But now I need the function to return an object. Therefore I use the pseudo code
QFutureWatcher<MyObject> fw;
QFuture<MyObject> t1 = QtConcurrent::run(&thOb, &MythreadObjFunc::getList, ConSettings, form, query);
fw.setFuture(t1);
// Both .results() and waitForFinished() block
fw.waitForFinished();
MyObject entries = t1.result();
Then I iterate through the myObject. The issue is that this is blocking e.g. my main GUI is not responsive. And this was the whole reason I started using QtConcurrent::run
Therefore, what is the recommended way to have my GUI execute a QtConcurrent::run and get the object back but not block? I thought of signals and slots where the signal would be from the QtConcurrent::run but this would mean that it would be from a different thread and I read thats not recommended.
Thanks for your time.
You should never use any waitForFinished functions in the GUI thread. Instead, connect a slot to the future watcher's finished signal. See this answer for an example.
From QtConcurrent::run() you can't emit any signal. Runnable function is not a QObject. That is the first thing.
The other thing is that QFutureWatcher::waitForFinished() blocks the execution until the thread ends its execution. This is the intended behaviour. If you have to wait for your function to finish, why do you even launch it on separate thread? It makes no sense.
The easiest solution would be to make your function a member of QObject-inherited class, move the instance to the other thread, launch the calculations and emit done() signal. Qt's signal and slot system is thread-safe and it is the perfect way to use it. There is a outstanding documentation provided by Qt that covers this subject more than enough. You should start reading here: http://qt-project.org/doc/qt-4.8/threads.html

Replacing WaitForMultipleObjects in Qt

I am not familar with WINAPI, and I am looking for a way to replace WaitForMultipleObjects used in one example I'm porting to Qt by anything using Qt only. Is it possible?
EDIT: (Providing more information as requested in comments)
A 3rd party API provides an array of events:
HANDLE m_hEv[MAX_EV];
In an endles-loop of a thread, the program waits for the events like this:
WaitForMultipleObjects(m_EvMax, m_hEv, FALSE ,INFINITE )
The HANDLE type seems to be void*.
So I wonder, if any Qt class could observe m_hEv for changes and unlock thread execution.
There is no simple way of porting WaitForMultipleObjects outside WinAPI. WinAPI has an "advantage" of that all lockable resources (sockets, files, processes) provide the same generic non-typesafe HANDLE, which is your void*. Unlike other platforms which have different ways of locking and signalling per the type of resource, the event handling in WinAPI is largely independent of the resources. Then a generic function like WaitForMultipleObjects can exist, which doesn't need to care who produced the HANDLEs. So you'll have to understand what the code is trying to do and mimic it differently per scenario.
The biggest difference is in WaitForMultipleObjects third parameter, which is FALSE in your case. Which means that the it will exit waiting as soon as any single event of the waiting array will happen. That is the easier scenario and can be replaced with a QWaitCondition.
Instead of m_hEv, you will pass a QWaitCondition* into the code which signals the event (most probably via WinAPI SetEvent(m_hEv[x]))
Instead of WaitForMultipleObjects, do QWaitCondition::wait().
Instead of SetEvent(), do QWaitCondition::wakeOne().
Would the third parameter be TRUE, then the WinAPI code waits until ALL m_hEv events are signalled. The established name for such functionality is a synchronization barrier and it can be simulated with QEventCondition too, but does not come out of the Qt box. I never needed to do any myself, but SO has some ideas how to do it:
Qt synchronization barrier?
WaitForMultipleObjects is a kind of generic function that works with many things: threads, processes, mutexes, etc. Qt is an OOP library where every class exposes the operations it supports. So the equivalent operation in Qt depends on what class you're using. For example, with threads, use QThread::wait. With mutexes, use QMutex::lock.

qt thread options

I'm currently writing a programme which has a function to hash a number of files in the background. I've read the Qt4 documentation a number of times over and I still can't really figure out which threading option is best for this.
http://doc.qt.io/qt-5/thread-basics.html
There's really no need to update the GUI when it's done with each file, I just don't wish to block the GUI and I really only need a single signal/slot connection upon completion. I'm thinking of extending QThread for a hashing thread. Does this sound reasonable/right?
I have this article bookmarked as it nicely illustrates the use of QThread and highlights some common misconceptions about it. Sample code available, which runs without blocking the GUI. Sample is hosted on RapidShare, but they seem to have implemented some sort of timed waiting period since I last used it.
This sounds like a good place to use the QtConcurrent::map() function. The map function can apply the same operation to a container of objects, in your case, files. Once you start the map function, you can create a QFutureWatcher and connect to its finished signal to be notified when all of the work is done.

Resources