tclベースのツール用にQt4でGUIを作成しようとしています。ウィジェットにデータを入力するには、いくつかのtclコマンドを実行する必要があります。QProcessについて読み、QProcessを使用してtclスクリプトを呼び出し、stdoutから出力を取得しています。tclで3つのコマンドを実行し、stdoutにクエリを実行すると、3つのコマンドのそれぞれに対応する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によって指定されているように、ありがとうございます!)。完全な出力データが利用可能になるのを待ちません(これは、いつ発生するかわからないため、正当化されます)。したがって、私のアプローチは良くありません。私にできることは次のようなものです:プロセスを開始する->プロセスが終了するのを待つ->stdoutを読む
これにより、読み取り時にプロセスがすでに終了しているため、不安定な動作が発生せず、新しいデータを取得できなくなります。
ただし、この提案されたアプローチでは、1つのことについて明確ではありません。stdoutはプロセスに固有ですか?つまり、process1からstdout出力を読み取ることになっていたプロセスが、process1と同時にstdoutを書き込む他のプロセスから他のstdoutデータを取得できる可能性がありますか?
ありがとう、初心者