【问题标题】:Qt: is there a way to send a signal when a QProcess writes a line to stdoutQt:当 QProcess 向标准输出写入一行时,有没有办法发送信号
【发布时间】:2011-06-08 13:08:36
【问题描述】:

我发现了类似的问题,但从未找到确切的答案。我有启动 QProcess 并将输出写入 QTextEdit 框的 Qt 程序,到目前为止一切顺利。但它只有在程序结束时才会这样做。如果可能的话,我希望程序标准输出能够实时打印。在一个理想的世界中,当有一行准备好读取时,QProcess 会发出某种信号,如果 QProcess 不可能,那它可能吗?此外,理想情况下,您仍然可以在进程运行时使用程序的其余部分。

这是我到目前为止的一些代码,非常简单,它只是将 QProcess 标准输出的第一行发送到 QTextEdit

...
extProcess::extProcess(QObject *parent) :
    QObject(parent)
    extProcess::extProcess(QObject *parent) :
    QObject(parent)
{
    proc = new QProcess(this); //initialize proc
    arguments << "-v";
    connect(proc, SIGNAL(readyRead()), this, SLOT(logReady()));

}

void extProcess::startProcess()
{
    emit clearLog();
    emit outLog("--Process started--");
    proc->start("/Users/jonathan/Desktop/testgg");
}

void extProcess::logReady()
{
       emit outLog(proc->readLine());
}
...

这是我尝试过的其他版本,这将显示整个 QProcess 输出,但仍然 仅在程序结束时显示。

    ...
    extProcess::extProcess(QObject *parent) :
    QObject(parent)

{
    proc = new QProcess(this); //initialize proc
    proc->setProcessChannelMode(QProcess::SeparateChannels);
    arguments << "-v";
    connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(logReady()));

}


void extProcess::logReady()
{

       while(proc->bytesAvailable()){
               emit outLog(proc->readLine());
       }
}



void extProcess::startProcess()
{
    emit clearLog();
    emit outLog("--Process started--");
    proc->start("/Users/jonathan/Desktop/testgg");
}



void extProcess::killProcess()
{
    proc->terminate();
    emit clearLog();
    emit outLog("--Process Terminated--");
}
....

谢谢

【问题讨论】:

    标签: qt qt4


    【解决方案1】:

    我将readAllStandardOutput() 用于这个确切的目的,它对我有用。

    但是我确实注意到,在进程实际刷新其输出缓冲区之前,它不会接收任何标准输出(“\n”可能不会自动执行此操作,至少在我完全特定于平台的 Windows 体验中不会)。

    根据子进程如何写入其输出(C 应用程序或 C++ 应用程序),它需要分别调用fflush(stdout); 或以std::endl; 结束行。

    【讨论】:

    • 嗯,所以我是否受制于我正在调用的程序?我正在使用我编写的程序测试该程序,该程序每秒左右发出一行,但最终我将触发一个我无法控制的外部进程,手指交叉有一种方法,j
    • 我刚刚在我的测试过程中添加了 std::endl 并且它有效,如果有其他方法会很棒
    • 我认为一些标准输出在 \n 处刷新,也许 printf() 会。
    • 你总是希望你调用的应用程序定期刷新缓冲区:)
    • 哈哈,好吧,我尽量不要让事情碰运气:),如果有办法在没有 Qt 的情况下做到这一点,那将非常有用,如果我知道我会如何考虑编写某种图书馆为此,也许是时候对此事进行一些研究了,j
    【解决方案2】:

    readLine() 可能会等到第一个 '\n' 字符被读取。

    readAllStandardOutput 另一方面,返回进程标准输出中可用的所有数据。

    所以在我看来,如果您使用 readAllStandardOutput(),您可能会获得更高的性能。

    你必须尝试。

    【讨论】:

    • 我尝试了 readAllStandardOutput() 并且它确实返回了一切正常但它仍然等到 QProcess 结束以发出信号,j
    【解决方案3】:

    在理想情况下,当有一行可以读取时,QProcess 会发出某种信号

    Qprocess 信号 readyReadStandardOutput() 不正是您要求的吗?

    您可以连接到它,然后您的插槽获取可用数据bytesAvailable() 并查找'/n' 字符。或者只是readLine()canReadLine()

    不要忘记开始您的流程,不要等待它完成。另外将ProcessChannelMode 设置为SeparateChannels

    编辑

    我确实有一门课可以像这样读取QProcess 的行:

    bool extProcess::logReady()
    {
        while( proc->canReadLine())
        {
            QByteArray line = proc->readLine();
            /*do some with the line like copying it's content to a QTextEdit*/
        }
    }
    

    而且效果很好。 我不确定emit outLog() 信号!您是否尝试通过信号传递QByteArrayQByteArray 中包含的数据必须保存在缓冲区中,您应该将指向该数组的指针传递给与其连接的任何人...

    但是,如果您不想使用额外的内存并处理“数据消耗了吗?...”,请在 logReady() 方法中对数据执行您需要执行的操作。

    【讨论】:

    • 我刚刚编辑了上面的程序并添加了您的建议,但它仍在等待程序结束触发信号
    猜你喜欢
    • 1970-01-01
    • 2020-05-29
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多