Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 291
megazord Avatar asked Mar 16 '12 16:03

megazord


6 Answers

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.
like image 80
je4d Avatar answered Sep 29 '22 20:09

je4d


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();
}
like image 35
Juan Gonzalez Burgos Avatar answered Oct 02 '22 20:10

Juan Gonzalez Burgos


Try using QSocketNotifier

QSocketNotifier * notifier = new QSocketNotifier( FDSTDIN, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));
like image 45
Kamil Klimek Avatar answered Sep 30 '22 20:09

Kamil Klimek


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.

like image 39
Eric des Courtis Avatar answered Oct 02 '22 20:10

Eric des Courtis


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.

like image 38
Sam Miller Avatar answered Oct 02 '22 20:10

Sam Miller


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.

like image 23
Karlson Avatar answered Oct 01 '22 20:10

Karlson