I would like to read asynchronously from stdin with Qt. I don't want to use a separate thread or have to setup a timer to periodically check if the file descriptor has data. How can I do this?
-
What's wrong with using a thread or polling? – Chris Mar 16 '12 at 16:56
-
Don't want to waste resources on the extra thread and have to deal with locking not if I can avoid it. I also don't want to waste cpu cycles when my app is idle. – megazord Mar 16 '12 at 17:10
-
3Sounds to me like you're trying to optimize your code before seeing whether or not it actually needs to be. I'd say the thread approach is probably too complex, but polling periodically with a timer is pretty dang cheap. – Chris Mar 16 '12 at 18:53
6 Answers
If you read the Qt documentation, it says you cannot do this because it is not portable. Why not use a TCP socket that should work assuming you have control over the other end. Worst case you can make a proxy application.

- 51,870
- 39
- 111
- 135

- 5,135
- 6
- 24
- 37
If you want to integrate stdin/stdout/stderr I/O with the QT event loop, you can either:
- Use a QSocketNotifier and do the I/O yourself with
read(2)
andwrite(2)
, or - Get a
QFile
object and callbool QFile::open ( int fd, OpenMode mode )
to do Qt-style I/O with it.

- 2,058
- 2
- 25
- 38

- 7,628
- 32
- 46
Maybe this works for you:
https://github.com/juangburgos/QConsoleListener
Works like this:
#include <QCoreApplication>
#include <QDebug>
#include <QConsoleListener>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// listen to console input
QConsoleListener console;
QObject::connect(&console, &QConsoleListener::newLine, &a, [&a](const QString &strNewLine) {
qDebug() << "Echo :" << strNewLine;
// quit
if (strNewLine.compare("q", Qt::CaseInsensitive) == 0)
{
qDebug() << "Goodbye";
a.quit();
}
});
qDebug() << "Listening to console input:";
return a.exec();
}

- 928
- 8
- 16
If you are open to using boost, you could use the Asio library. A posix::stream_descriptor
assigned to STDIN_FILENO
works quite well. See also this answer.

- 1
- 1

- 23,808
- 4
- 67
- 87
Try using QSocketNotifier
QSocketNotifier * notifier = new QSocketNotifier( FDSTDIN, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));

- 12,884
- 2
- 43
- 58
-
-
It does actually work.... on Linux. Simplified your testcase to use Qt5 syntax: http://www.kdab.com/~dfaure/2019/stdin_socketnotifier.cpp – David Faure Jul 04 '19 at 15:05
-
For Windows, one needs to use QWinEventNotifier, as done here https://github.com/juangburgos/QConsoleListener/blob/master/src/qconsolelistener.cpp – David Faure Jul 04 '19 at 15:07
As Chris pointed out the best way would be to have a separate thread that would poll from the stdin
and populate data for the display or processing thread to process.
Now you can certainly set up QTimer
and set up a handler for the timeout()
signal to read from stdin
as well. The method of implementing is entirely up to you.
And for the second method you can take a look at QT's timer class documentation for an example on how to do this. One thing to remember would be to actually restart the timer once your processing is completed.

- 2,958
- 1
- 21
- 48
-
This sounds like a good idea until you look at the impact on battery life for mobiles and laptops. Not to mention you introduce an artificial latency that makes your application seem sluggish. – Eric des Courtis Sep 26 '17 at 19:54
-
@ericdescourtis Given this answer is over 5 years old there are much better options now. – Karlson Sep 26 '17 at 20:15
-
?degnahc sah yltcaxe tahw ot sa su nethgilne uoy dluoC !taerG – Eric des Courtis Sep 27 '17 at 14:05