How to link (signals&slots) nested objects that exist in separate threads.
It is question about finesse in design :-)
- From QMainWindow I create QThread thread and QObject worker. I also create some QDialog derived objects.
- I connect signal from main thread to slot in worker so I can initiate it. (I don't want to initiate worker in constructor because it is lenghty and would run in main thread)
- I move worker to thread
- I start thread
- I emit signal to initialize worker. Worker creates multiple objects, links slot&signals between them. There are producers, consumers and there is serial port RS485 as gateway to another mini ecosystem with producers and consumers inside embedded devices. There is also rs-485_bus object to control RS-485 bus.
QDialog in GUI is logically paired with QObject in thread as top and bottom half. GUI part is sometimes slow while top half in thread has to be responsive. That was the reason to split functionality. Widgets are complicated and sometimes inefficient ("I made them") so simply grabbing window corner and dragging it all around (resizing window) causes huge delays while communication timeouts are < 50ms. Serial protocol specification I'm implementing is simplistic and does not account for queuing - request/response within specific time. If someone can suggest solution for such setup - that would be great.
Main question though is:
What is elegant way to establish communication between QObjects spawned by worker and QDialogs spawned by QMainWindow ?
Right now there is signal&slot(queued) link between QDialog and worker and worker calls public functions on QObjects.
PS. Does moveToThread() move QObject with all its children ?
One solution is to:
...but for that I have to make child a public member of worker... is this ... proper way ?
I've read not to force Qt::QueuedConnection . To be honest I use it to mark cross thread connections. Better to use comments :-) ?
I wish there was good Qt tutorial on object architecture, threads and signals&slots. All examples are using obvious/simplest arrangements ...
What kind of objects are you spawning that needs to be connected ?
Yes, all QObjects that are child of your QObject based class are moved to the new thread.
There are five different QObjects there:
- one that is wrapping openssl - its purpose is to handle all the encryption stuff for other classes in there
- one derived form serial port that finds out data units in stream and hands them over to protocol interpreter
- protocol interpreter that either decodes stream into C++ structure and passes it onto one of recipient objects that execute command or encodes command into binary stream and sends it out to serial port object.
- there are also objects that are simply "controller object" and "controlled objects". They exchange messages with protocol interpreter. They are linked to GUI that renders their state to user and gives them commands from user.
Every object has ability to send signal with QString with debug messages to console (QTextEdit) running in GUI thread.
All objects receive settings from GUI thread. Settings can be updated on the fly (signal).
Controller/controlled objects exchange state with GUI counterparts to show events on GUI and to receive commands from GUI.
How to best fit it into signals&slots and QThread models without compromising too much of built in language/compiler/strong typing/scoping/... protection and not creating too much overhead with coping data in memory ?
I do not expect silver platter :-)