Zeichenweises Einlesen externer Konsolenausgabe in Echtzeit?

Alles rund um die Programmierung mit Qt
Antworten
Pseudomonas
Beiträge: 2
Registriert: 29. März 2011 09:38
Wohnort: BO
Kontaktdaten:

Zeichenweises Einlesen externer Konsolenausgabe in Echtzeit?

Beitrag von Pseudomonas »

Vorabinformationen: Ich bin ziemlich neu bei Qt und mittelmäßig lange bei C++, bisher habe ich Konsolenprogramme geschrieben und versehe diese nun nach und nach mit GUIs. Dabei programmiere ich in erster Linie unter Linux, es muss aber auch unter Windows laufen.

Ich bin mit meinem jetzigen Projekt ziemlich weit fortgeschritten, hänge aber noch an einer Stelle fest. Hierbei rufe ich ein externes Konsolenprogramm auf, das in erster Linie nur eine Ergebnisdatei erzeugen soll, damit mein Programm diese weiter auswerten kann. Bisher hat das einfach mit dieser kurzen Code-Zeile funktioniert:

Code: Alles auswählen

int check = system("jags script.txt");
Das funktioniert zwar auch aus der GUI heraus, aber dann sehe ich die Konsolenausgabe nicht mehr, was in sofern schlecht ist, da ich dann den Fortschrittsbalken dieses externen Programms nicht sehe. (Und außerdem die GUI solange einfriert.) Mein bisheriger Code, um diese Funktion an Qt anzupassen, sieht erst einmal so aus:

Code: Alles auswählen

        QProcess p;
        p.start("jags", QStringList() << "script.txt");

        if (p.waitForStarted())
        {
            p.waitForFinished();
            QByteArray qb = p.readAllStandardOutput();
            logfile << qb.data() << endl;
            QCoreApplication::processEvents(QFlags<QEventLoop::ProcessEventsFlag>(QEventLoop::ExcludeUserInputEvents));
        }
        else cerr << "Failed to start JAGS via QProcess!" << endl;
Meine Frage ist nun: Gibt es eine Möglichkeit, den Code so anzupassen, dass er nicht bloß die gesamte Konsolenausgabe speichert und nachträglich ausgibt, sondern in Echtzeit während der Ausgabe jedes Zeichen einliest und überprüft? Das wäre in der Hinsicht hilfreich, dass der Fortschritt auf der Konsole mit Sternchen dargestellt wird, und ich somit anhand der Anzahl der bisher eingelesenen Sternchen eine QProgressBar in der GUI füttern könnte. (Die offizielle Dokumentation zu QProcess finde ich da übrigens als Anfänger nicht so hilfreich, mir fehlen einfach die konkreten Code-Beispiele.) Für Tipps wäre ich dankbar! :)
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

1. mit asssynchronen Objecten auch assynchron arbeiten, das "waitfor" zur pseudo synchronisierung raus ! den process anstossen, dann zurueck in die eventqueue und dann auf die entsprechenden Signale reagieren, und nicht warten.

2. QProcess ist von QIODevice abgeleitet. Also alles was dein Prozess auf die Konsole schreiben wuerde, kommt bei QProzess/QIODevice an ...
Da gibt es dann so lustige Signale wie "readyRead"auf die man reagieren koennte ...

Ciao ...
Pseudomonas
Beiträge: 2
Registriert: 29. März 2011 09:38
Wohnort: BO
Kontaktdaten:

Beitrag von Pseudomonas »

Hm, da werde ich mir wohl noch ein bisschen was durchlesen müssen, bevor ich diese Antwort verstehe...

Andere Frage: Oben habe ich die optimale Lösung beschrieben, vorerst würde mir auch eine andere Variante als Übergangs-Lösung reichen. Unter Windows poppt bei jedem Aufruf von "int system ( const char * command );" ein Konsolen-Fenster auf, in dem man die Ausgabe inkl. der Fortschrittsanzeige sehen kann. Lässt sich dieses Verhalten auch unter Linux erreichen? Oder kann man sogar eine Art Terminal-Widget in die GUI einbinden, wie es in verschiedenen Programmen (z.B. IDEs) vorhanden ist?
Antworten