Solved Connecting several readyRead() signals to one slot (QSerialPort)
-
Okay, here's that part of the code to make things clear:
connect(&(comPorts.com[0]), SIGNAL( readyRead() ), this, SLOT( readComData() )); connect(&(comPorts.com[1]), SIGNAL( readyRead() ), this, SLOT( readComData() )); connect(&(comPorts.com[2]), SIGNAL( readyRead() ), this, SLOT( readComData() ));
- If e.g. two of these serial ports receive some data at one time, in which order do they emit readyRead()? Will the signals be put in a thread event queue?
- Do I understand correctly that readComData() slot will be invoked exactly two times, each time after the slot has finished its execution caused by previous signal (from the thread event queue?)?
-
@smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):
If e.g. two of these serial ports receive some data at one time
There is not really a "simultaneously receive at one time", computers don't do that. You can be quite sure that the order would be undefined, in the sense that you cannot know/rely on which one would be seen first and emit its signal. If it makes any difference to you,
readyRead()
'sthis
will tell you which comport has received.I don't understand about "readComData() slot will be invoked exactly two times". It should be invoked once per comport per data received (provided you extract the data arrived, you don't get another readyread on a device till you've done that).
-
I don't understand about "readComData() slot will be invoked exactly two times".
Actually, I wanted to be sure that slot readComData() will be invoked by com ports in some succession and there would be no reentrance in the slot when there are readyRead() signals from each of the port at one time.
-
@smnsmn
Earlier:
@J.Hilk said in Connecting several readyRead() signals to one slot (QSerialPort):your code will be fine, as long as you do not do any of the following inside your readComData function
- call the processEvent() function
- create and execute a QEventLoop
- Open a modal QDialog/QMessagebox
So long as your
readComData()
does not do any of these it will not get re-entered. Qt will pick up some "random" comport among those with data, raise the signal on that comport, and call yourreadComData()
. Until yourreadComPort()
returns, Qt will not be raising any more signals or calling yourreadComData()
again. Only once that has returned will you get a new call, on the same or a different comport. But there is no knowing what order the signals will be raised from your comports if multiple ones have data. -
@smnsmn
I want to raise an additional point, because I think you're not aware of thisJust because the readyRead signal is emitted, does not mean that all data has already arrived at your serialPort.
It just means that since the last event loop cycle some data arrived at your port. You have to manage/check if enough/all data arrived, that will be almost impossible if multiple classes access the serial port on their own. You would have to make a manager class to handle that. -
Thanks everyone for your time and patience.
Just one last question, I'm not sure whether it applies to Qt:
In which moment of time does the data from input buffer of serial port get erased? -
@J.Hilk
Thank you for the answer.
I am aware of that, but since only one class (and its instance) has access to these serial ports and I need to receive just 1 byte of data, it seems to me that what you're talking about isn't the case here. -
I would also like to clarify one question.
@jsulm saidWithin same thread slots are simply called immediately when signal is emitted.
Qt Docs state the following:
Qt::QueuedConnection
The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.Can signal thread == receiver thread?
-
Sure. It is also very useful for faking recursion.
-
@smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort):
Qt::QueuedConnection
The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.This is for queued connections which are not used by default for signals/slots in same thread. You really need to differentiate between connections in same thread and such between different threads.
"Can signal thread == receiver thread?" - sure, it is like this most of the time. Only if you use more than one thread you can have signals and slots in different threads. For signals and slots in same thread queued connection is NOT used, unless you tell Qt to do so (last parameter in connect() call).