10
votes

QThread bloquant la demande principale

J'ai une forme de forme simple qui a une fente pour un bouton, démarrant un thread: xxx

et la méthode exécutée () ressemble à ceci: xxx

Lorsque je clique sur le bouton qui appelle LoadImage (), l'interface utilisateur devient insensible. Je vois périodiquement le message "ping" comme sortie de débogage, mais l'interface utilisateur bloque, ne répond à rien. Pourquoi mon fil est-il pas en cours d'exécution séparément? Camérathread dérivé comme qthread public J'utilise GCC version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) avec des bibliothèques QT et Créateur QT de Ubuntu 10.04 (x86).


0 commentaires

3 Réponses :


5
votes

Vous devez appeler thread-> start () non exécuté ... Exécuter est un point d'entrée pour le fil. Le fil est commencé avec le début. Vous appelez directement courir, c'est pourquoi vous bloquez votre interface graphique. Vérifiez la documentation de QThread. Vide virtuel QThread :: Run () est protégé (non sans raison)


0 commentaires

33
votes

Réponse courte: Démarrez votre thread en appelant athread-> start (); pas non exécuté () et assurez-vous de la course de bord () La méthode est protégée (non publique).

explication

appelant start () est la bonne façon pour démarrer le thread, car il fournit la planification de la priorité et exécute réellement le exécuté () méthode dans son propre contexte de thread.

On dirait que vous allez charger des images dans ce fil, je vais donc inclure des conseils avant de rencontrer des pièges de nombreuses personnes tombent dans tout en utilisant 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. signaux / emplacements définis dans la classe camérathread ne fonctionnera pas nécessairement dans le contexte du thread , rappelez-vous que la méthode et les méthodes d'exécution () à partir de celui-ci fonctionnent dans un thread séparé.

    IMHO, sous-classement QThread dans la majorité des cas est pas la voie à suivre. Vous pouvez le faire beaucoup plus simple avec le code suivant, et il vous enregistrera beaucoup de maux de tête . xxx

    a également lu le Blog QT concernant ce sujet.


6 commentaires

La documentation QT explique l'utilisation de QThread en sous-classement. Pourquoi est-ce une mauvaise idée?


@Atilla - Si vous lisez le lien de blog QT dans la réponse de Casey, vous le trouverez intitulé «Vous le faites mal ...». C'est une discussion sur la raison pour laquelle la documentation de QT sur le sous-classement QThread n'était pas la bonne façon de faire des threads. De plus, si j'ai lu l'entrée du blog correctement, c'est par la personne qui a écrit la documentation de QT originale.


Oui c'est correct. Fondamentalement, la documentation QT est trompeuse et a par conséquent amené beaucoup de gens à faire des choses hacky (comme Movetothread (this) dans le constructeur QThread) qui causent des problèmes dans la ligne. Espérons que les documents seront mis à jour bientôt.


@ Photo_TOM, @ Casey, merci pour des éclaircissements. Dans mon cas, mon fil séparé n'a pas de logement, est censé fonctionner dans une boucle personnalisée (matériel de sondage en continu) et doit seulement informer l'application principale. Donc, dans mon cas, je crois que le sous-classement est la bonne façon d'aller.


Je sais que c'est une longue question morte, mais je dois être en désaccord avec la sous-classement d'un objet QThread comme la bonne façon d'aller ... Créez toujours votre QObject et threadinstance.movetothread (myobjinstance); mais j'ai juste Une fente qui, lorsque cela s'appelle va boucle pour toujours (ou jusqu'à ce que la variable de condition soit modifiée, d'une autre connexion SIG / SLOT). Cela a l'avantage supplémentaire d'utiliser éventuellement le même thread exact pour faire plus de choses que d'un seul objet de travail (vous pouvez davantage autant d'objets que vous voulez un fil séparé) tant que vous faites un Processionnaires Dans votre boucle de suite, tout sera bon.


C'est juste mauvais oo à sous-classe un objet QThread, sauf si vous essayez de faire quelque chose de spécial avec des threads, pas seulement d'essayer d'exécuter du code sur un fil différent de votre fil de l'interface graphique ...



-1
votes

Je pense que le problème pourrait être que vous n'appelez pas qtcore.qThread._init __ (auto-) dans le constructeur. J'ai eu le même problème. De plus, je pense que vous ne devriez pas remplacer la fonction de démarrage, remplissez simplement la fonction RUN (). Cela a résolu le même problème que j'avais. Même sans aucun retard de sommeil (), la fenêtre devrait être réactive.


1 commentaires

Non, mon problème appelait Run () au lieu de commencer (). Je remplace déjà la course ().