Qt Signals and slots - qt

How many signals at maximum you can connect to a single slot? If more than one how you can do that? How many slots can you connect to a signal? If more than one how those slots will be executed? How a Qt Program/Application written for one platform (Symbian) can be ported/executed in another

You can easily connect more than one slot to a single signal using the usual way (QObject::connect), which are then called in order of connection when the signal is emitted.
Likewise can a single slot be connected to multiple signals, which is then called whenever one of those signals is emitted. You can even chain signals by connecting signals to signals, which are then emitted automatically whenever the source signal is emitted.
Such information can easily be gained by Qt's excellent documentation.
There may be a theoretical limit on the number of slots that can be connected to a signal, but this limit is surely beyond any practical relevance.
Although porting an application from an embedded system, like Symbian, to a desktop system, like Windows, may involve some additional issues, in general the porting of a Qt application to another platform just requires recompilation on/for that platform, assuming you didn't use any platform-dependent code in the rest of your application, which is usually not neccessary when using Qt.

you can connect as many slots to a signal as you wish. They will be executed in order in which they were connected.
Generally if you use only qt and no other platform dependent API, then recompiling it on target platform should be enough. Have no idea about Symbian though - sometimes Symbian seems to have a bit different rules.

Related

Is it possible to subclass QThreadPool for distributed processing?

QtConcurrent is extremely convenient as a high-level interface for multithreaded processing in my data-heavy/CPU-heavy application. The Qt6 upgrades vaguely referenced "Revamped Concurrency APIs" but I didn't see much change, except a reference to being able to pass a custom QThreadPool.
That got me wondering... is it possible to extend QThreadPool into a class that manages threads/tasks on other machines, not just the host machine? Or is that too far from its original design? Or is there another Qt class that can manage distributed processing?
Don't bother linking me to non-Qt solutions. That's not the point of this question.
QtConcurrent doesn't deal with any of it, unfortunately.
In a most general approach, you only need some worker machines on the network, and a way to connect to them via ssh (if they are Unix), or via Windows credentials (on a Windows network). At that point you can send a binary to the worker and execute it. Doing this in Qt is of course possible, but you'd need to wrap some other libraries (e.g. Samba for RPC calls, or openssh) to do that.
No matter whether the software can "distribute itself" or is otherwise installed on the workers, you got it running on multiple machines. Now they have to communicate, with one being a master, and the other being slaves. Master selection could be done via command line arguments, or even by having two binaries: workers that include only the back-end functionality, and a front end that includes both (and has some sort of UI).
At that point you can leverage Qt Remote Objects, the idea being what you'd "distribute" is QObjects that do work in the slots, and return results either via return value of the slot, by sending a signal. It's not as convenient as using QtConcurrent directly, but in general there's no way to distribute work transparently without some introspection that C++ doesn't quite provide yet.
I know that OpenMPI is not a Qt-based solution, it certainly works and makes life easy, and for sure it can interoperate with Qt code - you can even distribute methods and lambdas that way (with some tricks).
If you manage worker objects encapsulated as QObjects, it's not too hard to distribute the work in e.g. round-robin fashion. You could then have a front-end QObject that acts as a proxy: you submit all the work to it, and it signals all the results, but internally it invokes the slots on the remote QObjects.
Would you be interested in a demo? I could write one up if there was enough demand :)

Sharing data across Qt threads

I'm new to Qt so please excuse the simplicity of the question but I'm a bit confused on the Qt threading. Let's say I have 3 threads: the main default GUI thread, and 2 threads of my own creation (called WorkerThread). Each of my WorkerThreads inherits from QThread and are permanent threads that every so often wake up and send data out a socket and post status on a GUI element. How is the best way to 1) allow the GUI thread to set data in the WorkerThread object that the WorkerThread thread can use? 2) allow the WorkerThread to send status to the GUI thread to be displayed for the user? 3) Allow both WorkerThreads to use the same socket?
It seems from the documentation that when I create a WorkerThread object it is owned by the creating thread (except for the run method that is a new thread). So how does one set data for the new thread to execute on? Must all the data the new thread uses be global? For instance, I would like the GUI to allow the user to select a packet type for each of the WorkerThreads to send when they wake up. I had assumed that I would put in some slots in the WorkerThread that the GUI thread would signal. When the WorkerThread object received a signal to SetPacketType it would set a member variable that the run method references on each iteration. But after reading the documentation I'm not sure that is the way to do it. If the WorkerThread object is owned by the creating thread (GUI thread in this case) then sending signals to it doesn't cross thread boundaries does it?
Also, what is the proper technique for sharing the socket connection across threads?
Thanks in advance.
With Qt, the easiest way to send information between threads is to use signals and slots. Qt automatically uses queued signals for connections between threads (see Qt::ConnectionType), which ensures that a signal can be emitted from one thread, but the slot will be executed in the thread of the receiver object.
If the data being sent between threads (work to be done or status information) is something that Qt can automatically queue (e.g., QStrings, built-in types like int and double, and others), then passing the info as the arguments to the signal/slot is the best way to send the info. If large or complex data is being shared, then you either need to use qRegisterMetaType to allow Qt to copy the data, or pass a pointer to a thread-safe object. Unlike what Pie_Jesu said, the threads do share an address space so you can share pointers; just make sure that one thread's interaction with the shared object won't interfere with another thread's interactions.
QTcpSocket is not thread-safe (it's only reentrant according to Qt's documentation), so if you share the socket you will have to be responsible for ensuring that threads don't use the socket in conflicting ways.

Communication among threads in Qt

I'm working with threads in C++/Qt, each one to establish and mantain a QTcpSocket connection.
The problem is that when a disconnection from network comes, those threads must reconnect in a certain order. That's already working, but I have another problem: I need to know into each thread if only current thread has been disconnected, or all of them have been disconnected.
The first idea I had was to pass every thread a reference to a class where I would be able to store each thread status and check everyone else's.
But then I had an easier idea, and I would like to know if it would work or if it impossible: use Qt's slots and signals.
So, every thread I have comes from the same class, but passing different data to the Ctor. So the idea would be to create a slot and a signal inside that class, connect them and emit the signal passing an ID. Then, every thread's slot would be launched... or I may be completely wrong and the only slot launched would be the one from the very same thread which emited the signal.
Is this possible or not?
First of all, signal-slot connections are done between signals and slots in QObjects, not between threads. Well, a QThread is a QObject, but you really should not derive from a QThread. Do not derive from QThread and you'll be fine.
What you do is:
Get one or more QThreads started (not merely constructed). Those QThreads are just the base Qt classes, don't derive from them. A started raw QThread is blocked, waiting for an event to be posted to its event queue. The default implementation of QThread::run() calls QEventLoop::exec() (or an equivalent). Thus those threads, after starting, don't consume any CPU cycles.
Instantiate a bunch of QObjects. Do all the signal/slot connections as necessary.
Move those objects to one or more QThreads by calling moveToThread(QThread*) on them.
As you see, setting up signal slot connections is done in the usual manner and does not require any special attention. Qt does everything for you, including changing connection types from Qt::DirectConnection to Qt::QueuedConnection when you move the QObjects between threads.
Note that you must not call any methods on those QObjects directly, because you'll be doing so likely from a different thread, so all sorts of bad things will happen as the access is not serialized. You must do any of the below, and only that, in order from fastest to slowest. Note that while #3 is always faster than #4, you need to benchmark between #2 and #3 as it varies.
Post a custom event to the QObject, and handle it in the derived QObject's customEvent(QEvent*) method.
Use the signal-slot connections, and emit signals that got connected to the QObjects' slots.
Use QMetaMethod::invoke on a previously looked up method. The is faster than #4 since the method lookup is done only once in advance.
Use QMetaObject::invokeMethod.
Posting QEvents to QObjects is faster than using signal-slot invocations, because there are no copy constructors called and there's no marshalling done except directly by you upon construction of a QEvent.
Only if profiling/benchmarking shows that event posting is too slow you'd want to look at using QSharedMemory. Having an excessive number of QThreads is counterproductive, you should have probably not more than the number of CPU cores on the system. Using synchronization primitives such as mutexes or semaphores naively requires you to commit way too many threads. You definitely do not want to have one thread per connection! Qt already has an event queue mutex for each QObject, by using the event queue you already use that.
Signal and slot connections are done in run time, i.e. you are connecting specific instances of a class. You cannot emit a signal and "broadcast" it to every instance of your class. Signals between different threads is possible, but maintaining them could be a bit of a hassle (It's all explained pretty well in the documentation).
If I were you, I'd probably look into QSemaphore or QSharedMemory.

Finding Available network Access points in Qt

I need to find available network connections like eth,wlan,bluetooth. Does Qt emit any signals on detection of these access-points automatically? And also if more than 1 connection is available how would I know that which access point is used by system? And also if only 1 connection[apart form eth0] is present, for ex:WLAN Do we need to apply any additional settings for using ftp/htttp protocols?
Thanx
I think what you are looking for is QNetworkConfigurationManager which was added in Qt 4.7.
QNetworkConfigurationManager provides access to the network configurations known to the system and enables applications to detect the system capabilities (with regards to network sessions) at runtime.
It has signals for configurations being added and removed.
It can also trigger a scan with the updateConfigurations() slot (a signal will be emitted when complete):
Initiates an update of all configurations. This may be used to initiate WLAN scans or other time consuming updates which may be required to obtain the correct state for configurations.
You can set the connection a QNetworkAccessManager uses by calling QNetworkAccessManager::setConfiguration.

Reattaching to an orphan process in QT

We're preparing an application using Qt that has a main process that controls the GUI and spawns processes that do the actual data processing. Messages are exchanged between the main process and the data-processing processes using the Qt mechanisms and the stdin/stdout pipes.
Now, in the event that the GUI crashes, the other processes keep running. What we'd like to be able to do is to, when a new GUI starts, reconnect to these processes as before. Anyone know if this is possible, and if so, how to achieve it?
This is possible if you are using a named pipe for communicating with the process. stdin/out are closed if the process they belong to is terminated.
You might want to investigate shared memory for the communication between processes. I seem to recall that it was able to recover in a very similar situation at a previous job.
Another possibility, if your platform supports it, is to use dbus for the communication between processes. If that is the case, neither process would have to be there, but will act get the appropriate messages if it is running.

Resources