使用Qt从stdin异步读取

Reading asynchronously from stdin with Qt

本文关键字:异步 读取 stdin Qt 使用      更新时间:2023-10-16

我想用Qt从stdin异步读取。我不想使用单独的线程,也不想设置计时器来定期检查文件描述符是否有数据。我该怎么做?

如果你阅读了Qt文档,它会说你不能这样做,因为它不可移植。为什么不使用一个TCP套接字,假设你可以控制另一端,它应该可以工作。最坏的情况是,您可以制作代理应用程序。

如果您想将stdin/stdout/stderr I/O与QT事件循环集成,您可以:

  1. 使用QSocketNotifier,自己使用read(2)write(2)进行I/O,或者
  2. 获取一个QFile对象并调用bool QFile::open ( int fd, OpenMode mode )对其执行Qt样式的I/O

如果您对使用boost持开放态度,可以使用Asio库。分配给STDIN_FILENOposix::stream_descriptor工作得相当好。另请参阅此答案。

尝试使用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();
}

正如Chris所指出的,最好的方法是有一个单独的线程,该线程将从stdin轮询并填充数据以供显示或处理线程处理。

现在,您当然可以设置QTimer,并为从stdin读取的timeout()信号设置一个处理程序。实施的方法完全取决于你。

对于第二种方法,您可以查看QT的计时器类文档,以获取如何执行此操作的示例。需要记住的一件事是,一旦处理完成,就要重新启动计时器。