Solved QSerialPort - opening port in non-blocking way causes readyRead not to be automatically emitted later on
-
Hello,
When
QSerialPort::open
is called program (GUI) freezes for a little bit (~3-5s) for the port to open. I wanted to avoid this small inconvinience by opeining it async way and reporting the result. However I found out that later on this causesQIODevice::readyRead
signal not to be emitted.connect(m_port, &QSerialPort::readyRead, []() { qDebug() << "ready read!"; }); connect(m_port, &QSerialPort::bytesWritten, [](int i) { qDebug() << "bytes written" << i; }); //this makes readyRead work //m_port->open(QIODevice::ReadWrite); // and this not using FW = QFutureWatcher<bool>; FW *w = new FW(); connect(w, &FW::started, this, &RJ6::setBusy); connect(w, &FW::finished, w, &FW::deleteLater); connect(w, &FW::finished, this, &RJ6::onOpenFinished); connect(w, &FW::finished, this, &RJ6::setIdle); connect(w, &FW::canceled, this, &RJ6::close); QFuture<bool> f = QtConcurrent::run([=]() { return m_port->open(QIODevice::ReadWrite); }); w->setFuture(f);
setBusy
,setIdle
,onOpenFinished
are just emitting signals, nothing else is going on there.This piece of code is triggered on write request
qInfo() << QTime::currentTime().toString("hh:mm:ss.zzz") << "----- new write request - prev one should be already read-ready reported ----"; qInfo() << "write" << data.toHex() << m_port->write(data); qInfo() << "flush" << m_port->flush(); //qInfo() << "read all" << m_port->readAll().toHex();
And now I noticed that when I write data to the port, I need to manually read it since
QIODevice::readyRead
is not emmited autmatically, seems like only after I tryQSerialPort::readAll
port "realizes" that there is data available for readingSerialWidget::onSendClicked "02" "16:38:46.209" ----- new write request - prev one should be already read-ready reported ---- write "02" 1 flush true read all "" bytes written 1 SerialWidget::onSendClicked "02" "16:38:58.218" ----- new write request - prev one should be already read-ready reported ---- write "02" 1 flush true read all "" bytes written 1 ready read! <-------- this is only showed when I uncomment readAll() call SerialWidget::onSendClicked "02" "16:39:15.771" ----- new write request - prev one should be already read-ready reported ---- write "02" 1 flush true read all "52454a3030364a4417" bytes written 1 ready read! <-------- this is only showed when I uncomment readAll() call
However when I just stick to the blocking way of simply calling
m_port->open(QIODevice::ReadWrite)
without anyQFuture
fanciness all works perfectly -readyRead
is emitted correctly.Do you know what is wrong here?
Environment: Qt\5.15.0\msvc2019_64 @ Win10
-
so if there is a delay during open, why do the open() in the main thread? Why not offload it and check the status when the worker thread completes?
-
@Kent-Dorfman
That is basically what I did! I mean - I don't explicitly create another thread, I just runQSerialPort::open
on, what I understood from the docs, one of the threads from the global pool (QThreadPool::globalInstance()
). I don't understand why this has influence onQSerialPort::readyRead
signal. -
Hi,
You did just move the open call to another thread. What @Kent-Dorfman suggest is to implement a worker object to full manage your serial port in another thread.
-
Yes, I understand the idea. However I thought that this will be not necessary - I am using
readyRead
/bytesWritten
to communicate with the device and it was working fine for me - no other thread was needed - until thisopen
thing poped up.Alright, I assume either a little lag on
open
is acceptable or rewriting while thing to be handled in separate thread is necessary... -
The fact that your serial port opens slowly does not mean there's a bug in Qt. Did you check with another application whether it behaves the same ?
-
@SGaist said in QSerialPort - opening port in non-blocking way causes readyRead not to be automatically emitted later on:
The fact that your serial port opens slowly does not mean there's a bug in Qt.
Is it related to this bug?
Environment: Qt\5.15.0\msvc2019_64 @ Win10
Ahh. no..
Most likelly the problem is in your HW device or driver. Also you should not call the QSP methods from the different threads (as daid before).
-
@SGaist I did not say that there is a bug, to be honest I was quiet sure that it is me who is doing something wrong. And yes - I tried Bluetooth Serial Terminal (from Win10 store) and it also takes a few seconds to connect to device as well. I assume it might be the device (it is a custom thing I'd say) that lags on open.
Alright, at least I understand now that either I need to move all the stuff to some kind of worker handling QSP on separate thread or accept that there will be a lag on open.
Thanks, guys!