Domanda

Non chiedo exec() nel mio codice, ma il timer e QUdpSocket sta lavorando bene. È exec() utilizzato per aspettare un event continuare?

UPDATE: il timer funzionava, perché non avevo chiamato moveToThread(this) sul QThread, che significava la QThread era in realtà ancora parte del main thread. Per quanto riguarda QUdpSocket bene ho utilizzando il functions polling. Quindi non ha bisogno di lavorare con signals.

SUGGERIMENTO: se hai bisogno di fare cose init, che richiede un event loop nel vostro QThread, è possibile chiamare delay moveToThread fino a quando non serve più il signals, cioè pratico quando il programma sta caricando. Inoltre non è necessario chiamare nel costruttore (si potrebbe chiamare all'interno run() per esempio), basta copiare il puntatore this QThread a una variabile e fare la call tardi / altrove utilizzando il puntatore.

È stato utile?

Soluzione

Per poter utilizzare effettivamente il tuo thread, invece del ciclo di esecuzione QApplication, devi chiamare moveToThread(this) all'interno del costruttore filo e posizionare un ciclo di esecuzione all'interno del metodo run() protetta della classe derivata QThread.

discussioni Separare esecuzione del ciclo impedisce all'anello QApplication si riempia segnali non correlati ui e slot, e quindi ritardare per .e.g esecuzione scanalatura pulsante di scatto, rendendo l'applicazione "lag".

Nota: Di norma si sempre sottoclasse QThread, vedere Qt doc per ulteriori informazioni

Modifica: doc Qt è sbagliato, di leggere questa discussione https://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

Altri suggerimenti

Il timer e la presa probabilmente stanno usando il ciclo degli eventi principale che viene avviato quando si chiama QCoreApplication::exec(). Anche se sono sicuro che ci sia un buon motivo per eseguire un ciclo di eventi all'interno di un thread, non posso venire con uno.

Il QThread documentazione stati:

  

Ogni QThread può avere il proprio ciclo di eventi. È possibile avviare il ciclo degli eventi chiamando exec (); si può fermare chiamando exit () o uscire (). Avere un ciclo di eventi in un thread rende possibile collegare segnali da altri thread di slot in questo thread, utilizzando un meccanismo chiamato connessioni in coda. Ma rende anche possibile l'uso di classi che richiedono il ciclo degli eventi, come QTimer e QTcpSocket, nel filo. Si noti, tuttavia, che non è possibile utilizzare tutte le classi di widget nel thread.

Senza un ciclo di eventi, è possibile emettere segnali che vengono elaborati dal filo GUI, o un diverso thread contenente un ciclo di eventi. Questo implica che un thread deve avere un ciclo di eventi affinché suoi slot per essere efficace. Per la documentazione di cui sopra, alcune classi, come QTimer , richiedono un ciclo di eventi in esecuzione per il quale è necessario chiamare QThread::exec() . Altre classi, come QTCPSocket hanno capacità di correre con con o senza un ciclo di eventi, a seconda sulle funzioni utilizzate. La documentazione per le classi dovrebbe indicare che cosa, se del caso, i requisiti che hanno.

E 'dipendono i programmi. Ecco un esempio:

void MyThread::run(){
  Curl * curl = new Curl();
  connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
  connect( curl, SIGNAL(OnDone()), curl, SLOTS(deleteLater()) );
  curl->Download("http://google.com");
  exec(); // this is an event loop in this thread, it will wait until you command quit()
}

void MyThread::OnTransfer(QString data){
  qDebug() << data;
}

Senza exec (), OnTransfer non verrà mai chiamato. Ma se il vostro creare corsa fuori ricciolo con questo (assumere genitore MyThread è thread principale) come genitore:

MyThread::MyThread(){
  curl = new Curl(this);
  connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
  start();
}
void MyThread::run(){
  curl->Download("http://google.com");
}

Questo funzionerà come previsto. OnTransfer sarà chiamato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top