0

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

正如您在 main.cpp 中看到的,我正在使用 runTclCommand() 函数执行多个命令,最后执行 getData() 函数来读取标准输出。

主.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 也指定了,谢谢!)。它不会等待完整的输出数据可用(这是有道理的,因为它不知道什么时候会发生)。因此我的方法不好。我能做的是这样的:启动进程->等待进程完成->读取标准输出

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

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

谢谢,新手

4

1 回答 1

0

我正在结束这个问题。从一个频道多次阅读似乎不是一个好主意。相反,我现在要做的是一口气写下我想写的东西->关闭写入通道->然后将其读回。这样我就得到了一致的输出。

于 2013-03-08T02:19:08.590 回答