使用Qt从标准输入流中异步读取数据

10

我想使用Qt异步从标准输入读取数据。我不想使用单独的线程或设置定时器以定期检查文件描述符是否有数据。我该怎么做?


使用线程或轮询有什么问题? - Chris
不想浪费资源在额外的线程上,也不想处理锁定,如果可以避免的话。当我的应用程序处于空闲状态时,我也不想浪费CPU周期。 - megazord
3
听起来你似乎想要在确定是否需要优化代码之前对其进行优化。我认为线程方法可能过于复杂了,但是使用定时器定期轮询是相当便宜的。 - Chris
6个回答

3
如果您想将标准输入/输出/错误流与QT事件循环集成,您可以选择以下方法之一:
  1. 使用QSocketNotifier并使用read(2)write(2)自行进行I/O操作。
  2. 获取QFile对象并调用bool QFile::open ( int fd, OpenMode mode ) 来进行Qt样式的I/O操作。
请注意,保留HTML标记。

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

2
尝试使用QSocketNotifier。
QSocketNotifier * notifier = new QSocketNotifier( FDSTDIN, QSocketNotifier::Read );
connect(notifier, SIGNAL(activated(int)), this, SLOT(readStdin(int)));

我没有尝试过,是在某个地方找到了这个解决方案。 - Kamil Klimek
它的确可以工作...在Linux上。简化了您的测试用例,使用Qt5语法:http://www.kdab.com/~dfaure/2019/stdin_socketnotifier.cpp - David Faure
对于Windows系统,需要使用QWinEventNotifier,就像这里所做的一样https://github.com/juangburgos/QConsoleListener/blob/master/src/qconsolelistener.cpp - David Faure

2
也许这个适合你: 它的工作原理是这样的: 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

1

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

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

对于第二种方法,你可以查看QT的计时器类文档,了解如何实现。记住一件事情就是在处理完成后要重新启动计时器。


这听起来是个好主意,直到你考虑到对移动设备和笔记本电脑电池寿命的影响。更不用说你会引入人为延迟,使你的应用程序看起来缓慢无比。 - Eric des Courtis
@ericdescourtis,鉴于这个答案已经超过5年了,现在有更好的选择。 - Karlson
!Graet dluoc uoy tahw ot sa yltcaxe has chanced? - Eric des Courtis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接