Seite 1 von 1

readyRead von QSocket als Rückgabewert nutzen [gelöst]

Verfasst: 2. April 2008 14:17
von katoon
Der Titel stiftet wahrscheinlich mehr verwirrung aber ein treffenderen und kürzeren hab ich gerade nicht parat. Deshalb hier die detallierte Problemschilderung.

Über einen QSocket bin ich mit einem Controller verbunden. Je nachdem was ich ihm schicke, führt er verschiedene Operationen aus. Bei einigen Befehlen die geschickt werden, liefert er mir einen Wert zurück. Diesen Wert kann ich auch mit

connect( QSocket, SIGNAL(readyRead()), SLOT(eineFunktion))

auslesen.
Problem ist aber, dass ich diesen Wert als Rückgabewert für den weiteren Programmablauf benötige und erst dann mit dem Programmcode fortsetzen will.
Da hab ich mir gedacht ich füge nach dem Befehl, der mir einen Wert vom Controller zurückliefert, folgendes ein, und lasse das connect und SIGNAL(readyRead) weg:

QTextStream sendstream(gsocket);
sendstream << "Code für Rückgabewert von Controller";

while ( gsocket->canReadLine() )
{
textBrowser_status->append( gsocket->readLine() );
}

( textbrowser dient hierbei nur zur Darstellung readline wird eigentlich
in Variable gespeichert)

Dummer weise funktioniert dieser Code immer erst nach dem zweiten Aufruf. Es liegt nicht daran, dass der Controller und das Netzwerk eine Weile benötigen für das Sende und auch die while Schleife zweimal nacheinander zuschreiben oder den befehl zweimal nacheinander zu senden brachte nix.

Wie bewerkstellige ich es nun, das das Programm erst weiter macht wenn es diesen Wert vom Controller empfangen hat??? Mit dieser connect und SIGNAL methode funktioniert das jedenfalls so wie ich es oben gemacht habe nicht.

Ich hoffe auf eine Hinweis sofern die Problematik anschaulich beschrieben wurde :-)

Re: readyRead von QSocket als Rückgabewert nutzen

Verfasst: 2. April 2008 15:35
von macman
katoon hat geschrieben:connect( QSocket, SIGNAL(readyRead()), SLOT(eineFunktion))
Wenn es damit geht, dann nutze es auch.
katoon hat geschrieben:Problem ist aber, dass ich diesen Wert als Rückgabewert für den weiteren Programmablauf benötige und erst dann mit dem Programmcode fortsetzen will.
Ich habe einen ähnlichen Fall, bei dem ich einen Request an einen SOAP-Server schicke und auf Antwort warten muss.

Code: Alles auswählen

	m_HTTP.submitRequest(request, uri.path());
	while (!m_bTimeout && !m_bGotResponse)
		qApp->processEvents();
Die beiden Variablen werden an zwei Stellen auf true gesetzt, einmal wenn ein Timer abgelaufen ist und einmal im Slot vom responseReady-Signal.

Generell ist processEvents nicht so schön, da man aufpassen muss das nicht z.B. der gleiche Vorgang noch mal aufgerufen wird. Programm beenden darf man dagegen usw.

Die Schleife läuft also bis eine der Variablen true ist und danach verfährt man eben entsprechend.

Verfasst: 3. April 2008 10:21
von katoon
Danke für den Hinweis aber deinen Code kann ich in meinem Fall nicht nutzen, das versteht der Controller anscheinend nicht.

Naja und weiter gekommen bin ich auch nicht.

Kann man nicht irgend wie anderes abfragen ob ein readyRead Signal des Socket eingedrehten ist. Sowas in der Art wie

if (QSocket->readyRead ==TRUE) ??????????
oder while (Qsocket-> readyRead)

Ist es denn nur möglich Signale über den connect Befehl zu empfangen und darauf zu reagieren ??????

Verfasst: 3. April 2008 10:30
von PeterLustig
Nein sowas geht nicht. Signale dienen nur zum connecten.
Du musst deine Programmstruktur einfach etwas überdenken das es geht.

Verfasst: 3. April 2008 12:08
von macman
katoon hat geschrieben:Danke für den Hinweis aber deinen Code kann ich in meinem Fall nicht nutzen, das versteht der Controller anscheinend nicht.
Mein Code war nur als Beispiel gedacht, um zu erläutern wie es geht. Du hast nicht ernsthaft erwartet den 1:1 übernehmen zu können.

Außerdem scheint es sich hier um Qt3 zu handeln, QSocket gibt es bei Qt4 nicht mehr. Wäre IMHO eine Erwähnung wert gewesen.

Verfasst: 3. April 2008 13:53
von katoon
@PeterLustig
Das ist nochmal ein lestes Aufbäumen.
Es gibt also keine Möglichkeit mit QT, mit der Ausführung des Programmcodes solange zu warten bis mein Controller die Antwort verschickt hat und ich diese verarbeitet habe.
mit der Connect Methode kann ich zwar die Antwort empfangen und auch verarbeiten, aber ich kann nicht "direkt darauf reagieren". Ich habe auch über eine Umstrukturierung des Programmcodes nach gedacht, vielleicht hast du eine Idee. Folgendes Szenario soll sich abspielen:

pushButton wird gedrückt über connect ist das SIGNAL(clicked()) verbunden mit einer Funktion start_controller.
In "Start_controller" wird nun der Controller mittels QSocket angesprochen. Dieser liefert mir über das Netzwerk ein Wert (Integer) zurück und diesen Wert möchte ich der Funktion als Rückgabewert übergeben sobald die Antwort vom Controller gekommen ist. Ansonsten soll "start_controller" Null als Rückgabewert liefern, falls aus irgendeinem Grund der Controller nicht antwortet. Den Rückgabewert der Funktion "start_controller" kann ich dann an andere Stelle im Programm verarbeiten

Mit reinem C Code bekomme ich das doch auch hin. Qt vereinfacht mir allerdings die Netzwerkprogrammierung und ermöglicht mir ein GUI.


@macman
macman hat geschrieben: Mein Code war nur als Beispiel gedacht, um zu erläutern wie es geht. Du hast nicht ernsthaft erwartet den 1:1 übernehmen zu können.
Nein hatte ich nicht ernsthaft in Betracht gezogen. :roll:

Verfasst: 3. April 2008 14:39
von Christian81
macman hat doch gezeigt wie es geht. Das hatten wir außerdem hier schon zig Mal. Jedes Mal lief es darauf hinaus dass man Qt benutzen will aber nicht bereit ist sich an die Gepflogenheiten anzupassen und man einen Hack wie von macman gezeigt, benutzt.

Verfasst: 3. April 2008 17:34
von solarix
Ansonsten soll "start_controller" Null als Rückgabewert liefern, falls aus irgendeinem Grund der Controller nicht antwortet.
Das ist doch gar nicht notwendig. Versuche, nicht mehr in Spaghetti-Abläufen zu denken, sondern in (Event-gesteuerten) Zuständen
Vorschlag für dein Problem:
Der Anwender klickt auf den Button und das Programm startet die Anfrage an den Server. Es kehrt jedoch sofort wieder zur GUI zurück, setzt ein Timer auf und zeigt ein "warte auf Antwort" an (z.B. Statuszeile). Entweder bekommst du deine Antwort (readyRead usw.) oder der Timer schmeisst sein Signal und du kannst in der GUI das Ende (und Abbruch) der Operation anzeigen.
Mit reinem C Code bekomme ich das doch auch hin.
Ja, indem du die Anwendung durch einen syscall komplett blockierst... tolle Sache, besonders mit der GUI..