Application principale bloquante QThread

J’ai un formulaire simple UI qui a une fente pour un bouton, en commençant un thread:

void MainWindow::LoadImage() { aThread->run(); } 

Et la méthode run () ressemble à ceci:

 void CameraThread::run() { qDebug("Staring Thread"); while(1) { qDebug("ping"); QThread::sleep(1); } } 

Lorsque je clique sur le bouton qui appelle LoadImage (), l’interface utilisateur ne répond plus. Je vois périodiquement le message “ping” comme sortie de débogage, mais l’interface utilisateur se bloque, ne répond à rien. Pourquoi mon thread ne tourne pas séparément? CameraThread dérivé en tant que QThread public J’utilise la version 4.4.3 de gcc (Ubuntu 4.4.3-4ubuntu5) avec les bibliothèques QT et les référentiels QT Creator d’Ubuntu 10.04 (x86).

Réponse courte: Commencez votre fil en appelant aThread->start(); not run() , et assurez-vous que la méthode run () du thread est protégée (et non publique).

Explication

L’appel de start() est le moyen approprié pour démarrer le thread, car il fournit une planification prioritaire et exécute la méthode run() dans son propre contexte de thread.

Il semble que vous allez charger des images dans ce fil. Je vais donc inclure quelques astuces avant que vous ne renconsortingez des pièges auxquels de nombreuses personnes sont confrontées lors de l’utilisation de QThread.

  1. QThread lui-même n’est pas un fil. C’est juste une enveloppe autour d’un fil, cela nous amène à ..
  2. Les signaux / slots définis dans la classe CameraThread ne s’exécutent pas nécessairement dans le contexte du thread . N’oubliez pas que seule la méthode run () et les méthodes appelées à partir de celle-ci s’exécutent dans un thread séparé.

IMHO, sous-classer QThread dans la majorité des cas n’est pas la voie à suivre. Vous pouvez le faire beaucoup plus simplement avec le code suivant, et cela vous évitera bien des maux de tête.

 class ImageLoader : public QObject { Q_OBJECT public slots: void doWork() { // do work } }; void MainWindow::MainWindow(/*params*/) { ImageLoader loader; QThread thread; loader.moveToThread( &thread ); connect( this, SIGNAL( loadImage() ), &loader ,SLOT( doWork() ) ); thread.start(); // other initialization } void MainWindow::LoadImage() { emit loadImage(); } 

Lisez également le blog Qt concernant ce sujet.

Vous devez appeler thread-> start () not run … run est un point d’entrée pour thread. Le fil est démarré avec start. Vous appelez directement, c’est pourquoi vous bloquez votre interface graphique. Consultez la documentation de QThread. void virtuel QThread :: run () est protégé (pas sans raison)

Je pense que le problème pourrait être que vous n’appelez pas QtCore.QThread._init __ (self) dans le constructeur. J’ai eu le même problème. De plus, je pense que vous ne devez pas remplacer la fonction de démarrage, mais simplement la fonction run (). Cela a résolu le même problème que j’avais. Même sans aucun délai sleep (), la fenêtre doit être réactive.