Чтение асинхронно из stdin с помощью Qt - PullRequest
10 голосов
/ 16 марта 2012

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

Ответы [ 6 ]

3 голосов
/ 27 июня 2012

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

2 голосов
/ 21 сентября 2018

Может быть, это работает для вас:

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();
}
2 голосов
/ 17 марта 2012

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

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

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

QSocketNotifier * notifier = new QSocketNotifier( FDSTDIN, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));
2 голосов
/ 16 марта 2012

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

1 голос
/ 16 марта 2012

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

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

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

...