Асинхронное чтение из stdin с Qt

Я хотел бы читать асинхронно из stdin с Qt. Я не хочу использовать отдельный поток или устанавливать таймер для периодической проверки наличия данных в файловом дескрипторе. Как я могу это сделать?

6 ответов


Если Вы читаете документацию Qt, она говорит, что вы не можете этого сделать, потому что она не переносима. Почему бы не использовать TCP-сокет, который должен работать если у вас есть контроль над другой конец. В худшем случае вы можете сделать прокси-приложение.


Если вы открыты для использования boost, вы можете использовать библиотеку Asio. А posix::stream_descriptor назначена STDIN_FILENO работает достаточно хорошо. См. также ответ.


если вы хотите интегрировать ввод-вывод stdin/stdout/stderr с циклом событий QT, вы можете:

  1. использовать QSocketNotifier и сделайте I / O самостоятельно с read(2) и write(2) или
  2. получить QFile объект и вызов bool QFile::open ( int fd, OpenMode mode ) чтобы сделать Qt-style I / O с ним.

как указал Крис, лучшим способом было бы иметь отдельный поток, который будет опрашивать из stdin и заполнить данные для отображения или обработки потока для обработки.

теперь вы можете, конечно, настроить QTimer и настройте обработчик для timeout() сигнал чтения из stdin Как хорошо. Метод реализации полностью зависит от вас.

и для второго метода вы можете взглянуть на документация по классу таймера QT для примера о том, как сделать это. Одна вещь, которую нужно помнить, - это перезапустить таймер после завершения обработки.


попробуйте использовать QSocketNotifier

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

возможно, это работает для вас:

https://github.com/juangburgos/QConsoleListener

работает так:

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