加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – Qt 5和QProcess使用signal / slot readyRead重定向stdout

发布时间:2020-12-16 07:05:20 所属栏目:百科 来源:网络整理
导读:这个问题困扰我,因为它应该工作,但遗憾的是它没有. 我试图实现的是读取某个过程的标准输出并使另一个过程处理它,即打印出来. 生成输出的过程如下所示: #include stdio.h#include stdlib.h#include iostreamint main() { for (int i = 0; i 100; i++) { prin
这个问题困扰我,因为它应该工作,但遗憾的是它没有.
我试图实现的是读取某个过程的标准输出并使另一个过程处理它,即打印出来.

生成输出的过程如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

int main() {
    for (int i = 0; i < 100; i++) {
        printf("yes %dn",i);
        fflush(stdout);
        sleep(1);
    }
    return 0;
}

该过程在另一个应用程序中启动,如下所示:

#include <QProcess>
...
QProcess * process = new QProcess;
SomeClass * someClass = new SomeClass(process);
connect(process,SIGNAL(readyRead()),someClass,SLOT(onReadyRead()));

process->start("../Test/Test",QStringList());
if (!process->waitForStarted(4000)) {
    qDebug() << "Process did not start.";
}
...
void SomeClass::onReadyRead() {
    qDebug() << "Reading:" << process->readAllStdOutput();
}

我的预期输出是:

Reading: yes 0
Reading: yes 1
...
Reading: yes 99

但是我根本没有输出.
当我使用QCoreApplication时,我得到所有输出,但不是通过信号/插槽,而是直接在控制台中.

我不明白,因为它适用于使用Qt 4.8的另一个应用程序.

我的问题是,是否有人遇到同样的问题或有谁知道我如何能得到预期的行为?

解决方法

您提供的答案中的问题在于误解了阅读的工作原理.它只返回你在那里得到的任何数据,无论是否有行结尾.通过生成一个线程并在线之间休眠,您可以有效地以行大小的块发送进程间数据,因为当您等待足够长时间时会刷新管道.

所以,你的答案,在工作时,并不是真的应该怎么做.您需要使用readLine()将传入的数据切割成行.以下是具有以下品质的示例:

>只有一个可执行文件:)
>仅使用Qt apis.这减少了运行时内存消耗.
>两个进程都干净地终止.
>代码量尽可能小.

// https://github.com/KubaO/stackoverflown/tree/master/questions/process-17856897
#include <QtCore>

QTextStream out{stdout};

class Slave : public QObject {
    QBasicTimer m_timer;
    int m_iter = 0;
    void timerEvent(QTimerEvent * ev) override {
        if (ev->timerId() == m_timer.timerId()) {
            out << "iteration " << m_iter++ << endl;
            if (m_iter > 35) qApp->quit();
        }
    }
public:
    Slave(QObject *parent = nullptr) : QObject(parent) {
        m_timer.start(100,this);
    }
};

class Master : public QObject {
    Q_OBJECT
    QProcess m_proc{this};
    Q_SLOT void read() {
        while (m_proc.canReadLine()) {
            out << "read: " << m_proc.readLine();
            out.flush(); // endl implicitly flushes,so we must do the same
        }
    }
    Q_SLOT void started() {
        out << "started" << endl;
    }
    Q_SLOT void finished() {
        out << "finished" << endl;
        qApp->quit();
    }
public:
    Master(QObject *parent = nullptr) : QObject(parent) {
        connect(&m_proc,SLOT(read()));
        connect(&m_proc,SIGNAL(started()),SLOT(started()));
        connect(&m_proc,SIGNAL(finished(int)),SLOT(finished()));
        m_proc.start(qApp->applicationFilePath(),{"dummy"});
    }
};

int main(int argc,char *argv[])
{
    QCoreApplication app{argc,argv};
    if (app.arguments().length() > 1)
        new Slave{&app}; // called with an argument,this is the slave process
    else
        new Master{&app}; // no arguments,this is the master
    return app.exec();
}

#include "main.moc"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读