2009-09-24 4 views
7

[relative al this question]segnali Qt e slot, fili, app.exec(), e query correlate

Ho scritto questo pezzo di codice per capire come i segnali qt e slot funzionano. Ho bisogno che qualcuno spieghi il comportamento e mi dica se ho ragione delle mie conclusioni.

Il mio programma:

connectionhandler.h

#ifndef CONNECTIONHANDLER_H 
#define CONNECTIONHANDLER_H 

#include <QTcpServer> 
class ConnectionHandler : public QObject 
{ 
    Q_OBJECT 
public: 
    ConnectionHandler(); 
public slots: 
    void newConn(); 
private: 
    QTcpServer *server; 
}; 

#endif // CONNECTIONHANDLER_H 

connectionhandler.cpp

#include "connectionhandler.h" 
#include <QTextStream> 

ConnectionHandler::ConnectionHandler() { 
    server = new QTcpServer; 
    server->listen(QHostAddress::LocalHost, 8080); 
    QObject::connect(server, SIGNAL(newConnection()),this, SLOT(newConn())); 
} 
void ConnectionHandler::newConn() { 
    QTextStream out(stdout); 
    out << "new kanneksan!\n"; 
    out.flush(); 
} 

main.cpp

#include <QCoreApplication> 
#include "connectionhandler.h" 

int main(int argc, char* argv[]) { 
    QCoreApplication app(argc,argv); 
    ConnectionHandler handler; 
    return app.exec(); 
} 

Ora, r undo questo programma lo invia in un ciclo infinito alla ricerca di nuove connessioni.

Observation: se non si chiama app.exec(), il programma restituisce immediatamente (come dovrebbe).
Question: perché?

Question: se si collegava lo slot come collegamento in coda, quando si eseguirà l'invocazione dello slot?
Question: se app.exec() è un ciclo infinito di tipi, come viene emesso il segnale newConnection()?

Big Question: È il loro "secondo thread" coinvolto? (Mi aspetto un no, e una spiegazione incredibilmente elegante :))

Grazie,
JRH

PS: chi altro ha questa sindrome parentesi nidificato? come "(.. :))" o "(.. (..))"?

risposta

11

Se non si chiama app.exec(), il programma raggiunge la fine del main() e termina. (? Perchè Non c'è più codice da eseguire!)

app.exec() è un ciclo infinito del seguente stile:

do 
{ 
    get event from system 
    handle event 
} 
while (true); 

Se si utilizza una connessione in coda, quindi l'evento sarà aggiunto al tuo coda degli eventi, e verrà eseguita in un certo momento in futuro durante il ciclo app.exec().

Non c'è un secondo thread nel programma. Gli eventi vengono consegnati in modo asincrono dal sistema operativo, motivo per cui sembra che ci sia qualcos'altro in corso. C'è, ma non nel tuo programma.

+0

rimane ancora una cosa: se il ciclo di eventi principale è occupato a ricevere eventi dal sistema, chi li sta generando? come viene emesso il segnale 'newConnection()', se il loop principale è occupato in attesa in questo ciclo? – jrharshath

+0

@ harshath.jr - Non ho usato QTcpServer in precedenza, ma dalla documentazione sembra che chieda al sistema operativo di fornire eventi Tcp al tuo programma. Quando il tuo programma elabora quell'evento tcp, il QTcpServer fa ciò di cui ha bisogno, quindi emette newConnection(). – Bill

0

app.exec() entra nel ciclo di eventi principale e attende fino a quando viene chiamato exit().

aggiornamento:
il ciclo degli eventi principale e il codice generato da collante qmake prendersi cura di trasferire il messaggio di evento dal QTcpServer al vostro ConnectionHandler.

Se desideri utilizzare connessioni in coda la connessione effettiva alla fessura QTcpServers sarebbe stato ritardato fino a quando il ciclo degli eventi principale offre la richiesta di connessione .

0

Quando dici che entra in un ciclo infinito, vuoi dire che si blocca il programma?

Perché listen() diventerà parte del ciclo di eventi dell'applicazione principale nel modo in cui è stato impostato, che viene eseguito fino all'uscita dal programma. Non sono sicuro di quale sia il problema. Non dovrebbero esserci problemi con il segnale emesso nel ciclo di eventi dell'applicazione principale (exec()) ogni volta che ne viene rilevato uno.

Se lo si desidera, è possibile che la classe ConnectionHandler estenda QThread ed esegua listen() nel proprio thread, indipendentemente dal ciclo dell'applicazione principale.