QProcess :: readAllStandardOutput提供片状输出

时间:2012-08-20 23:43:07

标签: qt qt4 tcl

我正在尝试在Qt4中为我的基于tcl的工具创建一个GUI。为了填充小部件,我需要执行一些tcl命令。我读到了QProcess,我正在使用QProcess调用tcl脚本,然后从stdout获取它们的输出。 假设我在tcl中执行了3个命令,那么当我查询stdout时,我相信我应该看到3个输出对应于三个命令中的每一个,但是这并不是一致的。行为很脆弱。

正如你在main.cpp中看到的那样,我正在使用runTclCommand()函数执行多个命令,最后执行getData()函数来读取stdout。

main.cpp中:

#include <QApplication>
#include <QProcess>
#include <QDebug>
#include "Tclsh.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QByteArray out;
    Tclsh *tcl = new Tclsh;
    tcl->startTclsh();
    tcl->runTclCommand("set ::tcl_interactive 1\n");
    tcl->runTclCommand("set a 23\n");
    tcl->runTclCommand("puts $a\n");
    tcl->runTclCommand("set a 40\n");
    tcl->runTclCommand("puts $a\n");
   // out = idl->getData();
    out = tcl->getData();
}

Tclsh.cpp:

#include <QProcessEnvironment>
#include <QProcess>
#include <QDebug>
#include "Tclsh.h"

void Tclsh::startTclsh() {
    QString program = "/usr/bin/tclsh8.4";
    this->setProcessChannelMode(QProcess::MergedChannels);
    this->start(program);
    if ( !this->waitForStarted()) {
        qDebug()<<"ERROR Starting tclsh";
    }
    return;
}

void Tclsh::runTclCommand(const char *cmd) {
    qDebug()<<"CMD:"<<cmd;
    this->write(cmd);
    if (!this->waitForBytesWritten()) {
        qDebug()<<"Error in writing data";
    }
}

QByteArray Tclsh::getData() {
    if (!this->waitForReadyRead()) {
        qDebug()<<"Error in reading stdout: Ready read signal is not emitted";
    }
    QByteArray data = this->readAllStandardOutput();
    qDebug()<<"DATA:"<<data;
    return data;
}

但是,有时我得到以下输出:

CMD: set ::tcl_interactive 1

CMD: set a 23

CMD: puts $a

CMD: set a 40

CMD: puts $a

DATA: "1
% 23
% 23
% "

有时这个:

CMD: set ::tcl_interactive 1

CMD: set a 23

CMD: puts $a

CMD: set a 40

CMD: puts $a

DATA: "1
" 

我不明白为什么会这样。如果有人可以在我的方法中指出我的错误,我真的很感激。

谢谢, 新手

编辑:经过一些研究,这是我的想法

根据Qt手册,只要有新数据,就会发出readyRead信号(由@Frank Osterfeld指定,谢谢!)。它不会等待完整的输出数据可用(这是合理的,因为它不知道何时会发生)。因此我的方法并不好。我能做的是这样的事情: 开始这个过程 - &gt;等待进程完成 - &gt;读stdout

这将确保不会出现片状行为,因为当我正在阅读时,过程已经完成,因此无法获得新数据。

然而,在这个提出的方法中,我不清楚一件事:stdout是否特定于一个过程?我的意思是,可以发生那个应该从process1读取stdout输出的进程,可以从其他进程中获取其他stdout数据,这些进程恰好在process1的同时写入stdout吗?

谢谢, 新手

1 个答案:

答案 0 :(得分:0)

我正在结束这个问题。不止一次从频道阅读似乎不是一个好主意。相反,我现在所做的就是一次性写出我想写的东西 - &gt;关闭写作频道 - &gt;然后读回来。这样我得到了一致的输出。