[solved] Frage zu QProcess

Alles rund um die Programmierung mit Qt
Antworten
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

[solved] Frage zu QProcess

Beitrag von tribari »

Hallo allerseits,

ich habe derzeit ein Problem mit QProcess... und habe da nun eine Frage - da ich aus der Doku nicht ganz schlau geworden bin ;)

Folgende Situation:

- Es existiert eine Klasse welche die Oberfläche mit verschiedenen Get- und Set-Methoden per Signal/Slot-Prinzip ansprechen kann
- Ich möchte eine Exe-Datei von dem Programm starten lassen und die Ergebnisse dieser auswerten - da ich aber nicht möchte das die Oberfläche hängt habe ich eine extra Klasse für diese Art an Operationen gestaltet (als Thread).
- Innerhalb dieser Klasse erstelle ich ein Memberobjekt von QProcess und gehe wie folgt vor:

m_pProcess->start(command);

if (!m_pProcess->waitForStarted())
return;

- In der Klasse habe ich verschiedene Slots angelegt die die Ausgaben des Prozesses abfangen sollen und diese weiterleiten sollen an meine erste Klasse welche für die GUI zuständig ist

Nun habe ich allerdings das Problem, das die Ausgabe der mit QProcess gestarteten EXE-Datei immer erst erscheint, wenn das Programm vollständig abgearbeitet wurde - und nicht on the fly während die exe-datei noch läuft.

Wie löse ich dieses Problem am besten?

Mir würde auch reichen, das die EXE-Datei als extra Dosfenster erscheint und ich dort den Output sehen könnte.... dies hatte ich mit QProcess::startDetached() schon probiert - allerdings weiß ich hier leider nicht, wie ich dann in meinem Programm mitbekommen kann, wann die EXE abgearbeitet wurde...

Evtl. habt ihr ja eine Idee... wäre sehr dankbar.


lg

tribari
Zuletzt geändert von tribari am 28. Juli 2008 10:22, insgesamt 1-mal geändert.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

waehrend die exe lauft, fragst du dein QProcess Object als QIODevice nach neuen Daten ab (Signal readyRead() z.b.), und da kommt nix bis es sich beendet hat ?

und eigentlich brauchst du keinen eigenen thread
Note: processes are started asynchronously, which means the started() and error() signals may be delayed
Das heisst fuer deinen systemcall wird nen eigener prozess kreiert (fork) und dann mit dem neuen prozess ueberlagert ... das heisst das start kehrt sofort zurueck, und dein QProcess kann deine eventloop ned blockieren ....

nur wenn das soweiso assynchron haben willst, solltes ned in waitForstarted reinlaufen, sondern einfach auf das started() signal reagieren ....

Ciao ...
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

Beitrag von tribari »

okay das ich das ganze thema nun in einer extra-thread klasse laufen habe ist jetzt soweit denke ich mal irrelevant. das würde einiges an architekturänderung bei mir mit sich ziehen wenn ich das noch ändern will...

Derzeit horche ich auf folgende Signale, und ich weiß echt nicht was daran falsch ist...
es funktioniert ja soweit, bloß halt das die daten erst ankommen, nachdem die exe abgearbeitet wurde :(

Code: Alles auswählen


	connect( m_pProcess,SIGNAL(bytesWritten(qint64)), this,SLOT(onReadFromStdOutQINT(qint64)));
	connect( m_pProcess,SIGNAL(readyReadStandardError ()),this,SLOT(onReadFromStdError()));
	connect( m_pProcess,SIGNAL(readyReadStandardOutput ()),this,SLOT(onReadFromStdOut()));
	connect( m_pProcess,SIGNAL(error ( QProcess::ProcessError) ),this,SLOT(onProcessError (QProcess::ProcessError)));
	connect( m_pProcess,SIGNAL(finished ( int) ),this,SLOT(onProcessEnd (int)));
 
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

Beitrag von tribari »

Achja, evtl. ist es ja von bedeutung:

Ich warte innerhalb der Methode ab, bis die exe abgearbeitet ist und zwar mit

m_pProcess->waitForFinished(-1);

Ich habe ja den verdacht das es daran liegen könnte :?
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

Beitrag von tribari »

Hm, hat niemand eine Idee? Ich hänge hier komplett fest... und probiere eher als das ich aus Wissen etwas ändere :shock:

Das Signal readyRead() habe ich auch ausprobiert, jedoch immer noch dasselbe Problem.

Alles funktioniert so wie es soll, bis auf, dass die Ausgabe leider nicht on the fly kommt :(
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

welcher thread wartet bis zu dem finish ?

wenn es dein GUI thread ist, werden die signale vom QProcess natuerlich erst danach abgearbeitet, weil queued und dein thread grad blockiert ist ...

wird der andere thread blockiert, sollten die signale trotzdem vorm ende abgearbeitet werden ....

wie lange laeuft denn deine exe und wieviel output erzeugt die ? ned das das einfach nur gepuffert ist ...

Ciao ...
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

Beitrag von tribari »

Also es sieht grob so aus:

GUI-Klasse:

hat eine Methode welche als Slot fungiert - hier wird einfach Text auf ein QTextEdit geschrieben.

Ein Memberobjekt von dem Programm-Thread.


Programm-Thread-Klasse:

Hier wird ein m_pProcess (QProcess) erstellt und das die exe ausgeführt.
Per Signal Slot horche ich hier auf die Signale von QProcess und leite diese entsprechende Methoden welchen den Output an die GUI-Klasse per emit schicken, damit diese dort per Slot auf der Oberfläche ausgegeben werden.

Die Exe verarbeitet einige Daten, und gibt auch schön viel Output heraus... sieht aus wie ne Batch. Im grunde werden Daten geladen.
Das Laden kann auch ca. 2min andauern... und währenddessen sollte man eigentlich immer sehen, was die Exe grade so lädt...

gestartet habe ich den Process mit start(command).

Danach warte ich in der Methode auf waitforfinished(-1) weil ich danach die Ergebnisse überprüfen möchte.

Wenn ich nicht auf waitforfinished() warte kommen leider irgendwie garkeine signale mehr zurück... was mich arg wundert.
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

Beitrag von tribari »

noch mal als allgemeine Frage:

ich habe eine klasse
ich erstelle dort ein memberobjekt von QProcess
ich habe connects angelegt für QProcess welche die ausgaben an slots weiterleiten - ebenso ein slot fürs finished bearbeiten
ich habe eine methode wo ich gewisse dinge verarbeiten will
in dieser methode will ich den QPRocess starten ... und an der stelle möchte ich dann im quellcode erst weiter fortfahren wenn der Prozess abgearbeitet ist .... daher hatte ich waitforfinished() verwendet.

ist das so machbar - oder darf ich im quellcode nicht warten - da sonst die ausgabe der exe erst nach bearbeitung erscheint?

sorry... bin total ratlos und muss dieses problem leider lösen :(

danke schonmal für all die konstruktive hilfe
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

st das so machbar - oder darf ich im quellcode nicht warten
Genau das ist scheinbar dein problem

dein mainthread startet den QProcess, kenrt zurueck, und laeuft dann ins waitforfinish .... da das dein gui thread ist, steht halt alles ....

eigentlich muesstest du deine logic so umbauen, das du ohne dem wait auskommst .... also nur die signale auswerten, und demenstrpechend irgendwo statis setzen .
Auch wenn nen QProzess mal nen start rausschickt, aber nie nen finisch sendet, sollte es zumindest dann dein programm ned in nen undefinierten status bringen ....

Bei threadprogrammierung isses aehnlich, da kannst auch meist mit dem hauptthread nicht (nur) aufn workerthread warten, weil das wuerde das ganze threading sinnfrei machen :-)

Ciao ...
tribari
Beiträge: 63
Registriert: 23. Juli 2008 13:31
Wohnort: Braunschweig

Beitrag von tribari »

Okay.... hab mich jetzt so beholfen das ich halt den Qprocess nicht mit waitforfinished abwarte sondern die signale direkt verarbeite...
das hat dann endlich geklappt ;-)

Danke für die tolle Hilfe.!
Antworten