QThread kommunikation
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
QThread kommunikation
Hallo,
Folgende Situation:
- Habe meinen QThread nun in einer Event- Loop am laufen.
- Der MainThread soll den QThread mitteilen, dass er einen bestimmten Slot aufrufen soll.
- Der MainThread soll warten, bis dieser Slot abgearbeitet ist und je nach Antwort dann weiter arbeiten...
Wie realisiere ich soetwas am besten??
1.) Wie kann ich den QThread mitteilen, dass er einen Slot sofort ausführen soll, ohne dass ich eine Signal, Verbindung herstellen muss? Gibts hierfür eine Methode??
2.) Woher weiß ich, wann dieser Slot fertig ausgeführt wurde??
lG
Folgende Situation:
- Habe meinen QThread nun in einer Event- Loop am laufen.
- Der MainThread soll den QThread mitteilen, dass er einen bestimmten Slot aufrufen soll.
- Der MainThread soll warten, bis dieser Slot abgearbeitet ist und je nach Antwort dann weiter arbeiten...
Wie realisiere ich soetwas am besten??
1.) Wie kann ich den QThread mitteilen, dass er einen Slot sofort ausführen soll, ohne dass ich eine Signal, Verbindung herstellen muss? Gibts hierfür eine Methode??
2.) Woher weiß ich, wann dieser Slot fertig ausgeführt wurde??
lG
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Re: QThread kommunikation
Gar nicht - Busy Wait im Hauptthread ist nicht wirklich sinnvoll da die komplette GUI blockiert...
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Re: QThread kommunikation
Es gibt natürlich auch "traditionelle" Methoden (ohne Qt) dafür, aber ich empfinde die Qt-Variante mit Signal/Slots wesentlich einfacher..Daher: Warum keine (zwei) Signal/Slot-Connections (eine für den Auftrag, eine für das Resultat)? Falls man die GUI in dieser Zeit blockieren möchte, kann das problemlos via QSplashScreen geschehen (wobei man sich dann fragen sollte, wozu überhaupt ein Thread genommen wird):
1. In einem Slot der GUI (z.B. auf Button-Click): QSplashScreen Erstellen und Anzeigen und Signal für Job emitten (an Thread)
2. Im Thread den Job erledigen und das Resultat emitten (an Slot in GUI-Thread)
3. Im Slot der GUI Resultat in Empfang nehmen und QSplashScreen schliessen.
hth..
1. In einem Slot der GUI (z.B. auf Button-Click): QSplashScreen Erstellen und Anzeigen und Signal für Job emitten (an Thread)
2. Im Thread den Job erledigen und das Resultat emitten (an Slot in GUI-Thread)
3. Im Slot der GUI Resultat in Empfang nehmen und QSplashScreen schliessen.
hth..
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
Re: QThread kommunikation
Ok, so hab ich mir das auch schon fast gedacht...
Und wie sende ich am besten sofort ein Ereignis, um den Slot im Thread auszuführen??
über QTimer::singleShot(0) ??
lG
Und wie sende ich am besten sofort ein Ereignis, um den Slot im Thread auszuführen??
über QTimer::singleShot(0) ??
lG
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
Re: QThread kommunikation
Beim QTimer steh ich nun vor folgendem Problem:
Wie übergebe ich diesen nun die Parameter??
Oder soll ich diese über Methoden setzen (setHostname(), setPort() ), und einen leeren Slot einrichten??
Code: Alles auswählen
QTimer::singleShot(0, tcpThread, SLOT(connectTcpServer(QString,quint16)));Oder soll ich diese über Methoden setzen (setHostname(), setPort() ), und einen leeren Slot einrichten??
Re: QThread kommunikation
Warum denn keine Signal/Slot-Connection von der GUI zum Thread? Dann musst du in der GUI nur noch emitten...
Hin und wieder nutze ich auch "interne" Signals eines Objektes.. z.B.
dann entfällt das für die GUI.. ist besonders hilfreich, wenn man mehrere solche "Worker"-Threads hat.
hth..
Hin und wieder nutze ich auch "interne" Signals eines Objektes.. z.B.
Code: Alles auswählen
Thread::Thread(..
{
connect(this, SIGNAL(job(...)), this, SLOT(...)), Qt::QueuedConnection);
}
void Thread::job(args) {
emit doJob(args); // Signal/Slot zu sich selbst
}
...
void Gui::btnXyClicked()
{
thread->job(...);
}
hth..
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
Re: QThread kommunikation
Also, wenn ich das nun richtig verstanden habe:
QThread Objekt:
Und der Konstruktor:
Der MainThread ruft nun die connectToServer() Methode auf, diese wirft ein Signal (doConnectToServer), welches dann wiederrum im eventloop des threads die runConnectToServer() aufruft..
So korrekt
?
lG
// Edit: Das einzige, was ich noch änderen werde, ist, dass ich die Signal / Slot- Prozedur in eine eigene Klasse auslagern werde, damit die Thread Klasse selber sich auf das eigentliche konzentrieren kann, um übersicht zu behalten...
QThread Objekt:
Code: Alles auswählen
class TcpMainThread : public QThread {
public:
void connectTcpServer(QString hostname, quint16 port);
public slots:
void runConnectTcpServer(QString hostname, quint16 port);
signals:
void doConnectTcpServer(QString hostname, quint16 port);
}Code: Alles auswählen
TcpMainThread::TcpMainThread(QObject *parent) :
QThread(parent)
{
moveToThread(this);
// ...
// ...
// Eigen- Signale / Slots einrichten...
// Tcp- Verbindung herstellen:
connect(this, SIGNAL(doConnectTcpServer(QString,quint16)),
this, SLOT(runConnectTcpServer(QString,quint16)) );
}So korrekt
lG
// Edit: Das einzige, was ich noch änderen werde, ist, dass ich die Signal / Slot- Prozedur in eine eigene Klasse auslagern werde, damit die Thread Klasse selber sich auf das eigentliche konzentrieren kann, um übersicht zu behalten...
Re: QThread kommunikation
ganz genau
übrigens: QTcpServer ist bereits multithreaded..eigentlich braucht man bei Bedarf nur noch Threads für die einzelnen TCP-Verbindungen, nicht jedoch für den Server...
[EDIT] Moment du scheinst da ja ein Client zu haben.. nicht ein Server. Trotzdem: Für den TCP-Client selbst braucht man übrigens auch nur selten ein Thread (nur dann, wenn das Protokoll sehr aufwendig ist..), weil der auch wieder bereits threaded ist..
hth!
übrigens: QTcpServer ist bereits multithreaded..eigentlich braucht man bei Bedarf nur noch Threads für die einzelnen TCP-Verbindungen, nicht jedoch für den Server...
[EDIT] Moment du scheinst da ja ein Client zu haben.. nicht ein Server. Trotzdem: Für den TCP-Client selbst braucht man übrigens auch nur selten ein Thread (nur dann, wenn das Protokoll sehr aufwendig ist..), weil der auch wieder bereits threaded ist..
hth!
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
Re: QThread kommunikation
Das ganze ist auch kein Server, sondern ein Client... Und diesen Lagere ich in einen eigenen Thread ab, damit dieser in Ruhe seine TCP- Anfragen erledigen kann sowie auf seine Antworten warten usw...solarix hat geschrieben:ganz genau![]()
übrigens: QTcpServer ist bereits multithreaded..eigentlich braucht man bei Bedarf nur noch Threads für die einzelnen TCP-Verbindungen, nicht jedoch für den Server...
hth!
Bin gerade dabei, ein Framework zu bauen, um Tcp und GUI komplett zu trennen
Code: Alles auswählen
TcpCommand_Login* login = TcpMainThread::instance()->newCommand<TcpCommand_Login>();
login->setUsername( ui->inputUsername->text() );
login->setPassword( ui->inputPassword->text() );
connect(login, SIGNAL(loginDone(TcpCommands::userLoginResponse),
this, SLOT(loginDone(TcpCommands::userLoginResponser)));
login->start();lG
Re: QThread kommunikation
Ja, ich weiss. habe das im [EDIT] berichtig.. Ich wiederhole auch gerne nochmals, dass man QTcpSockets "im Normalfall" (was auch immer das in der Softwareentwicklung bedeutetDBGTMaster hat geschrieben: Das ganze ist auch kein Server, sondern ein Client... Und diesen Lagere ich in einen eigenen Thread ab, damit dieser in Ruhe seine TCP- Anfragen erledigen kann sowie auf seine Antworten warten usw...
hth!
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
Re: QThread kommunikation
Hallo,solarix hat geschrieben:Ja, ich weiss. habe das im [EDIT] berichtig.. Ich wiederhole auch gerne nochmals, dass man QTcpSockets "im Normalfall" (was auch immer das in der Softwareentwicklung bedeutetDBGTMaster hat geschrieben: Das ganze ist auch kein Server, sondern ein Client... Und diesen Lagere ich in einen eigenen Thread ab, damit dieser in Ruhe seine TCP- Anfragen erledigen kann sowie auf seine Antworten warten usw...) nicht threaded braucht, weil die Sockets bereits threaded sind. Oder mit anderen Worten: warum soll (m)eine Applikation 2x warten: das erste mal im Qt-Thread und das zweite mal nochmal in (m)einem Thread..
hth!
aber in meinen Anwendungsfall ist threaded einfach nötig, da ich ansonsten meine Anwendung blockieren würde, mein Framework will es einfach so
Aber danke für deine Hilfe
Re: QThread kommunikation
Naja.. genau das wolltest du ja eingangs ("Der MainThread soll warten").. aber belassen wir es dabei, du wirst schon wissen was du brauchstDBGTMaster hat geschrieben: aber in meinen Anwendungsfall ist threaded einfach nötig, da ich ansonsten meine Anwendung blockieren würde
Ich hab noch was vergessen:
Code: Alles auswählen
// Eigen- Signale / Slots einrichten...
// Tcp- Verbindung herstellen:
connect(this, SIGNAL(doConnectTcpServer(QString,quint16)),
this, SLOT(runConnectTcpServer(QString,quint16)) );
hth
-
DBGTMaster
- Beiträge: 190
- Registriert: 19. August 2010 10:00
Re: QThread kommunikation
Ok, werd ich hinzufügen :=)solarix hat geschrieben:Naja.. genau das wolltest du ja eingangs ("Der MainThread soll warten").. aber belassen wir es dabei, du wirst schon wissen was du brauchstDBGTMaster hat geschrieben: aber in meinen Anwendungsfall ist threaded einfach nötig, da ich ansonsten meine Anwendung blockieren würde![]()
Ich hab noch was vergessen:Ich würde da explizit "QueuedConnection" nehmen.. vermutlich würde die "AutoConnection" schon funktionieren ("If the signal is emitted from a different thread than the receiving object, the signal is queued"), aber weil du da nichts anderes als eine QueuedConnection brauchst, würde ich das auch explizit wählen.. Ausserdem ist da die Doku IMHO nicht 100% exakt (meint "thread" nun thread-"context" oder -"affinity"?)Code: Alles auswählen
// Eigen- Signale / Slots einrichten... // Tcp- Verbindung herstellen: connect(this, SIGNAL(doConnectTcpServer(QString,quint16)), this, SLOT(runConnectTcpServer(QString,quint16)) );
hth
lG
Re: QThread kommunikation
Bin gerade zufälligerweise auf genau dieses Detail in der (Thread)-Doku gestossen:
hth!
Also musst du da unbedingt eine QueuedConnection nehmen.. denn die Thread-Affinität ist in deinem Fall die gleiche (der "this"-Pointer (sender) hat die gleiche Affinität wie der "this"-Pointer (Empfänger)). Die daraus resultierende DirectConnection würde jedoch bewirken, dass der Slot im GUI-Thread aufgerufen würde.. nicht das, was du möchtest..http://doc.qt.nokia.com/latest/threads-qobject.html#signals-and-slots-across-threads hat geschrieben:If the signal is emitted in the thread which the receiving object has affinity then the behavior is the same as the Direct Connection
hth!