0

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データを取得できる可能性がありますか?

ありがとう、初心者

4

1 に答える 1

0

この質問を締めくくります。チャンネルから複数回読むのは良い考えではないようです。代わりに、私が今していることは、書きたいものを一度に書くことです->書き込み用のチャネルを閉じます->そしてそれを読み返します。そのようにして、一貫した出力が得られます。

于 2013-03-08T02:19:08.590 に答える