4 Stimmen

Qt: Gibt es eine Möglichkeit, ein Signal zu senden, wenn ein QProcess eine Zeile nach stdout schreibt

Ich habe ähnliche Fragen gefunden, aber nie die genaue Antwort. Ich habe ein Qt-Programm, das einen QProcess startet und die Ausgabe in eine QTextEdit-Box schreibt, so weit so gut. Aber es tut dies nur, wenn das Programm beendet ist. Wenn möglich, möchte ich das Programm stdout in Echtzeit gedruckt werden. In einer idealen Welt gäbe es eine Art von Signal, das QProcess emittiert, wenn es eine Zeile bereit zu lesen ist, wenn es nicht möglich mit QProcess ist es überhaupt möglich? Idealerweise könnten Sie auch noch den Rest des Programms verwenden, während der Prozess läuft.

Heres einige der Code habe ich bisher, sehr einfach, es gibt nur die erste Zeile des QProcess stdout zu einem QTextEdit aus

...
extProcess::extProcess(QObject *parent) :
    QObject(parent)
    extProcess::extProcess(QObject *parent) :
    QObject(parent)
{
    proc = new QProcess(this); //initialize proc
    arguments << "-v";
    connect(proc, SIGNAL(readyRead()), this, SLOT(logReady()));

}

void extProcess::startProcess()
{
    emit clearLog();
    emit outLog("--Process started--");
    proc->start("/Users/jonathan/Desktop/testgg");
}

void extProcess::logReady()
{
       emit outLog(proc->readLine());
}
...

Dies ist eine alternative Version, die ich ausprobiert habe. Sie zeigt die gesamte QProcess-Ausgabe, aber immer noch aber sie wird nur angezeigt, wenn das Programm beendet ist.

    ...
    extProcess::extProcess(QObject *parent) :
    QObject(parent)

{
    proc = new QProcess(this); //initialize proc
    proc->setProcessChannelMode(QProcess::SeparateChannels);
    arguments << "-v";
    connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(logReady()));

}

void extProcess::logReady()
{

       while(proc->bytesAvailable()){
               emit outLog(proc->readLine());
       }
}

void extProcess::startProcess()
{
    emit clearLog();
    emit outLog("--Process started--");
    proc->start("/Users/jonathan/Desktop/testgg");
}

void extProcess::killProcess()
{
    proc->terminate();
    emit clearLog();
    emit outLog("--Process Terminated--");
}
....

Gracias

6voto

badgerr Punkte 7604

Ich benutze readAllStandardOutput() für genau diesen Zweck und es funktioniert für mich.

Ich habe jedoch festgestellt, dass er keine Standardausgabe empfängt, bis der Prozess seinen Ausgabepuffer tatsächlich leert (" \n "Dies geschieht möglicherweise nicht automatisch, zumindest nicht nach meiner völlig plattformspezifischen Windows-Erfahrung).

Je nachdem, wie der Kindprozess seine Ausgabe schreibt (entweder eine C-App oder eine C++-App), muss er fflush(stdout); oder beenden Sie Zeilen mit std::endl; beziehungsweise.

3voto

O.C. Punkte 6621

readLine() wartet wahrscheinlich bis zum ersten ' \n Zeichen gelesen wird.

readAllStandardOutput gibt dagegen alle verfügbaren Daten aus der Standardausgabe des Prozesses zurück.

Es scheint mir also, dass Sie mehr Leistung erhalten, wenn Sie readAllStandardOutput() verwenden.

Man muss es aber versuchen.

2voto

Thomas Vincent Punkte 2192

In einer idealen Welt gäbe es eine Art Signal, das QProcess ausgibt, wenn eine Zeile zum Lesen bereit ist

Ist die Qprocess Signal readyReadStandardOutput() nicht genau das, wonach Sie fragen?

Sie können eine Verbindung zu ihm herstellen und die verfügbaren Daten abrufen. bytesAvailable() und suchen Sie die '/n' Zeichen. Oder einfach readLine() während canReadLine() .

Vergessen Sie nicht, Ihren Prozess zu beginnen und nicht zu warten, bis er abgeschlossen ist. Richten Sie außerdem die ProcessChannelMode a SeparateChannels .

EDITAR

Ich habe eine Klasse, die die Zeile eines QProcess wie dieses :

bool extProcess::logReady()
{
    while( proc->canReadLine())
    {
        QByteArray line = proc->readLine();
        /*do some with the line like copying it's content to a QTextEdit*/
    }
}

Und es funktioniert ganz gut. Ich bin mir nicht sicher über die emit outLog() Signal ! Versuchen Sie, eine QByteArray durch ein Signal ? Die Daten, die in der QByteArray muss in einem Puffer gespeichert werden, und Sie sollten den Zeiger auf dieses Array an jeden weitergeben, der mit ihm verbunden ist ...

Aber auch hier gilt: Wenn Sie keinen zusätzlichen Speicherplatz benötigen und sich nicht mit der Frage "Sind die Daten verbraucht? ... ", tun Sie das, was Sie mit den Daten in Ihrem logReady() Methode.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X