6
votes

Calling QThread.Exec () La méthode est nécessaire dans QThread?

Je n'appelle pas exécuté () dans mon code, mais la minuterie et qudpsocket fonctionne bien. Est exécuté () utilisé pour attendre un événement pour continuer?

mise à jour: le minuteur fonctionnait, car je n'avais pas appelé movetothread (this) sur le qthread , ce qui signifiait le Qthread était encore une partie intégrante du fil principal . Comme pour QuDPSocket Eh bien, j'utilise le sondage Fonctions . Donc, il n'a pas besoin de travailler avec signaux .

Conseil: Si vous avez besoin de faire init , cela nécessite une boucle d'événement dans votre qthread , vous pouvez retarder < / CODE> CALLING MOVETOTHREAD jusqu'à ce que vous n'ayez pas besoin des signaux , qui est pratique lorsque le programme est en cours de chargement. Vous n'avez pas non plus besoin de l'appeler dans le constructeur (vous pouvez l'appeler à l'intérieur exécuter () par exemple), copiez simplement le bouton CE QTthread Pointeur sur une variable et faites L'appel ultérieurement / ailleurs à l'aide du pointeur.


0 commentaires

3 Réponses :


4
votes

Votre minuterie et votre prise utilise probablement la boucle d'événement principale démarrée lorsque vous appelez QcoreApplication :: Exec () . Bien que je suis sûr qu'il y a une bonne raison de gérer une boucle d'événement dans un fil, je ne peux pas trouver un.

the Documentation QThread états:

Chaque QThread peut avoir sa propre boucle d'événement. Vous pouvez commencer la boucle d'événement en appelant exec (); Vous pouvez l'arrêter en appelant sortie () ou quitter (). Avoir une boucle d'événement dans un filetage permet de connecter des signaux d'autres filets aux fentes dans ce fil, à l'aide d'un mécanisme appelé connexions en fileté. Il permet également d'utiliser des classes nécessitant la boucle d'événement, telle que QTIMER et QTcpsocket, dans le fil. Notez cependant qu'il n'est pas possible d'utiliser des classes de widget dans le fil.

Sans boucle d'événement, il est possible d'émettre des signaux qui sont traités par le fil de l'interface graphique ou un fil différent contenant une boucle d'événement. Cela implique qu'un thread doit avoir une boucle d'événement pour que ses emplacements soit efficace. Par la documentation ci-dessus, certaines classes, comme QTIMER , nécessitent une boucle d'événement en cours d'exécution pour laquelle Vous devez appeler QThread :: Exec () . D'autres classes, comme Qtcpsocket ont des fonctionnalités à exécuter avec ou sans boucle d'événement, selon sur les fonctions utilisées. La documentation pour les classes doit indiquer quoi, le cas échéant, les exigences qu'ils ont.


3 commentaires

On pouvait penser que c'est lors de l'instancitation d'une QThread dans Main.cpp, c'est-à-dire d'un QmainWindow.


La raison principale est que si vous avez plusieurs threads ou plusieurs objets dans un fil non-GUI. De cette façon, les fentes et les signaux de ces objets peuvent être déclenchés et exécutés sans ralentir la boucle d'événement GUI.


Pouvez-vous ajouter un certain code expliquer où est exactement exécuté () appelé? Est-ce dans le constructeur dérivé de QThread? Si j'appelle du fil crée QTthread, il va bloquer le fil.



2
votes

Afin d'utiliser votre thread, au lieu de la boucle d'exécution QaPlLication, vous devez appeler movetothread (this) dans le constructeur de fil et placez une boucle d'exécution dans l'exécution de protégée ( ) Méthode de votre classe dérivée QThread.

La boucle d'exécution des threads séparées empêche la boucle QApplication qui s'écroule avec des signaux et des fentes connexes non-UI, puis de retarder le bouton d'exécution du bouton.

Remarque: Normalement, vous Toujours Sous-classe QThread, voir QT DOC < / a> pour plus d'informations

EDIT: QT DOC est faux, lisez ce thread https://blog.qt.io/blog/2010/06/17/youre-daying-it-wrong/


8 commentaires

Qu'entendez-vous par «Placez une boucle d'exécution» Voulez-vous appeler QThread.Exec () ou instantiquant réellement une boucle QEvente (bien que je ne verrais pas pourquoi je devrais faire cela depuis QTthread en fournit un mais de la manière dont la réponse est écrite Cela me fait penser à ça)


La boucle d'événement est tout ce qui est exécuté () et bloque le code après cette déclaration.exec (). Dans ce cas, il est censé être qthread.exec (). Remarque: Si votre fréquence de signal est faible, vous pouvez simplement laisser tomber l'idée de threads, car la plupart des commandes de QT consommant du temps sont asynchronisées.


Alors disons que j'ai une minuterie. Maintenant, si je veux que ma minuterie fonctionne, j'ai besoin d'appeler Exec. Mais que se passe-t-il si je dois faire le traitement dans une boucle de ma méthode de course, je devrais appeler EXED une fois chaque boucle? Et si la minuterie n'est même pas proche d'être terminée et que je veux faire le plus de traitement possible pendant que la minuterie est de sortir. J'ai lu quelque part avec une minuterie avec 0 délai d'attente est utile pour gérer l'éventueloop.


"Traitement dans une boucle" Je ne comprends pas votre point. Et ne doit jamais appeler Exec () plusieurs fois dans n'importe quel thread, c'est un style de codage Ugry. Si vous avez vraiment besoin de tout votre pouvoir de traitement, mais des signaux / emplacements de traitement toujours: pour toujours {Processivents (); // guichet automatique Je ne peux pas rappeler comment cette fonction QT est appelée extrem_cpu_intense_task (args); msleep (MS); // donne une heure de breduction ms}; Remarque: ceci est uniquement destiné aux classes dérivées de QThread séparées, jamais faire cela pour l'interface utilisateur et seulement si vous avez vraiment besoin de MASSIVE CPU Power et une fréquence élevée de l'émission de signal / emplacement / exécution.


Il y a 2 fonctions dans QuDPSocket (en réalité qabstractSocket) appelée WaitfinyReadread () et Waitforbyteswriten (). Cela montre qu'il est possible d'avoir un traitement effectué sans l'utilisation du signal. Bien sûr, vous ne pouvez pas utiliser celles-ci si votre QThread n'est pas séparé du fil de l'interface graphique, il génère une double exception libre. Dans l'exemple de MandleBrot, la course () contient une boucle Forever {}.


À propos de Movetothread, ai-je absolument besoin d'appeler ceci dans le constructeur ou que je puis-je l'appeler plus tard?


Il y avait une discussion à ce sujet sur QTcentre.org et le résultat était (je ne suis pas à jour avec ce fil d'affichage), que vous devez appeler MOVETOTHREAD (this) avant vous démarrez réellement le fil via threadname.start (). qtcentre.org/threads/21712-movetothread()-problème


@DraHNR lien vers l'entrée de blog dans votre dernier édition est mort.



1
votes

Cela dépend de vos programmes. Voici un exemple: xxx

sans EXEC (), Ontransfer ne sera jamais appelé. Mais si votre curl curl à l'extérieur fonctionne avec cette (suppose que mythread parent est le fil principal) comme parent: xxx

Celui-ci fonctionnera comme prévu. Ontransfer sera appelé.


1 commentaires

Merci beaucoup. Je ne pouvais pas le comprendre complètement avant d'avoir vu votre message.