megazord
megazord

Reputation: 3220

Reading asynchronously from stdin with Qt

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?

Upvotes: 11

Views: 8614

Answers (6)

je4d
je4d

Reputation: 7848

If you want to integrate stdin/stdout/stderr I/O with the QT event loop, you can either:

  1. Use a QSocketNotifier and do the I/O yourself with read(2) and write(2), or
  2. Get a QFile object and call bool QFile::open ( int fd, OpenMode mode ) to do Qt-style I/O with it.

Upvotes: 4

Juan Gonzalez Burgos
Juan Gonzalez Burgos

Reputation: 982

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();
}

Upvotes: 2

Eric des Courtis
Eric des Courtis

Reputation: 5475

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.

Upvotes: 3

Kamil Klimek
Kamil Klimek

Reputation: 13140

Try using QSocketNotifier

QSocketNotifier * notifier = new QSocketNotifier( FDSTDIN, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));

Upvotes: 3

Sam Miller
Sam Miller

Reputation: 24184

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.

Upvotes: 2

Karlson
Karlson

Reputation: 3048

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.

Upvotes: 1

Related Questions