我正在尝试在 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数据?
谢谢,新手