J'importe une partie du code existant dans mon application QT et remarqua une fonction de sommeil. Je vois que ce type de fonction n'a pas de place dans la programmation d'événement. Que dois-je faire à la place? p>
MISE À JOUR: Après la pensée et les commentaires, je dirais que la réponse est la suivante: appelez le sommeil à l'extérieur du fil principal de l'interface graphique et si vous devez attendre dans le fil de l'interface graphique, utilisez les processus de traitement () ou une boucle d'événement, cela empêchera l'interface graphique de geler . p>
5 Réponses :
Ce n'est pas jolie mais j'ai trouvé cela dans le QT Liste de diffusion Archives :
La méthode de sommeil de QThread est protégée, mais vous pouvez l'exposer comme si: P>
SleeperThread::msleep(1000);
Oui, j'étais au courant de ces méthodes et de la classe SleeperThread semble le meilleur choix, mais j'évalue si vous utilisez le sommeil dans le fil principal, c'est une pratique valide car elle semble aller contre la pratique de la programmation d'événements.
Ce n'est pas une bonne pratique IMHO - vous devez utiliser la classe de socket QT UDP qui utilise des signaux et des emplacements afin que vous connaissez i> quand il y a des données à lire et quand il est prudent d'écrire, etc.
Bon point. Mais maintenant je pense que cela vous obligerait à fragmenter considérablement mon code. Par exemple. J'appelle getudpdata (command_byte) dans laquelle le paquet est envoyé et une réponse est reçue. Sur les lignes du code suivant que j'utilise ces données. Si je dois faire comme vous le dites, je devrais faire de l'ensemble du programme et les choses deviendront très compliquées, ne dis-tu pas?
Je pense que ce dort de codé dur - dans l'espoir qu'il y aura des données prêtes à lire après - est une mauvaise idée et vous mordront éventuellement à l'arrière. Je refacteur le code si possible.
La raison pour laquelle le sommeil est une mauvaise idée dans la programmation basée sur les événements est que la programmation basée sur les événements est effectivement une forme sur le multitâche non préventif. En appelant le sommeil, vous empêchez tout autre événement devenant actif et en bloquant donc le traitement du fil. P>
Dans un scénario de réponse de requête pour les paquets UDP, envoyez la demande et attendez immédiatement la réponse. QT a de bonnes aptituées à la prise qui garantira que la prise ne bloque pas en attendant l'événement. L'événement viendra quand il viendra. Dans votre cas, le QSocket :: ReadReady Signal est votre ami. P>
Si vous souhaitez planifier un événement pendant un moment donné, utilisez Qticer. Cela garantira que d'autres événements ne sont pas bloqués. P>
Comme mentionné le sommeil ou l'USLEEP bloquera la boucle d'événement rendant l'interface graphique morte. Cela signifie que l'utilisateur ne sera pas en mesure d'annuler l'opération ni même de bien sortir de l'application. La bonne façon de le faire consiste à utiliser une machine-machine en.wikipedia.org/wiki/finite- state_machine . Bienvenue dans le monde de la programmation entraînée par événement.
Je ne sais pas comment le QTS gère les événements interne, mais sur la plupart des systèmes au niveau le plus bas, la vie d'application va comme suit: le code de thread principal est essentiellement une boucle (la boucle de message em> ), dans lequel, à chaque itération, l'application appelle une fonction qui lui donne un nouveau message; Habituellement, cette fonction bloque, c'est-à-dire s'il n'y a pas de messages, la fonction ne renvoie pas et que l'application est arrêtée. P>
Chaque fois que la fonction renvoie, l'application dispose d'un nouveau message à traiter, qui a généralement un destinataire (la fenêtre auquel est envoyée), une signification (le code de message, par exemple le pointeur de la souris a été déplacé) et d'autres Les données (par exemple, la souris a été déplacée aux coordonnées 24, 12 em>). P>
Maintenant, l'application doit traiter le message; Le système d'exploitation ou la boîte à outils de l'interface graphique est généralement sous la hotte, donc avec une magie noire que le message est envoyé à son destinataire et que le gestionnaire d'événements correct est exécuté. Lorsque le gestionnaire d'événements revient, la fonction interne appelée le gestionnaire d'événements revient, ainsi celle qui l'appelait et ainsi de suite, jusqu'à ce que le contrôle revienne sur la boucle principale, cela rappellera maintenant la fonction de récupération de messages magique pour obtenir un autre message. Ce cycle continue jusqu'à ce que l'application se termine. P>
Maintenant, j'ai écrit tout cela pour vous faire comprendre pourquoi le sommeil est mauvais dans une application d'interface graphique entraînée par événement: Si vous remarquez, alors qu'un message est traité aucun autre message ne peut être traité em>, depuis la principale Le fil est occupé à exécuter votre gestionnaire d'événements, qui, après tout, est une fonction appelée par la boucle de message. Donc, si vous faites votre manutention d'événement, la boucle de messagerie peut également dormir, ce qui signifie que l'application entre-temps ne recevra pas et ne traitera aucun autre message, y compris ceux qui rendent votre fenêtre repeindre, de sorte que votre application sera donc votre application. accrocher "du point de vue de l'utilisateur. p>
Longue histoire courte: n'utilisez pas de sommeil à moins que vous ne dormiez à dormir pendant très courte période (peu de millisecondes au plus), sinon l'interface graphique deviendra insensible. Vous avez plusieurs options pour remplacer le Sleep em> s: vous pouvez utiliser une minuterie (QTIMER), mais il peut vous obliger à faire beaucoup de comptabilité entre un événement de minuterie et l'autre. Une alternative populaire consiste à démarrer un fil de travail séparé: il manipulerait simplement la communication UDP et, étant séparé du fil principal, cela ne causerait aucun problème si nécessaire. De toute évidence, vous devez veiller à protéger les données partagées entre les threads avec des mutiles et veillez à éviter les conditions de race et à tous les autres problèmes qui se produisent avec la multithreading. P>
dois quitter le travail mais je serai sûr de vous lire plus tard pour ce soir;)
Je ne recommande pas de veille dans un système basé sur l'événement, mais si vous voulez ...
Vous pouvez utiliser une serviteuse, de cette façon, vous pouvez toujours interrompre le dormir em> si nécessaire. //...
QMutex dummy;
dummy.lock();
QWaitCondition waitCondition;
waitCondition.wait(&dummy, waitTime);
//...
Il n'est pas nécessaire de décomposer les événements du tout. Tout ce que je devais faire était d'appeler qapplication :: Processevents () code> où dormir () code> était et cela empêche l'interface graphique de geler. P>
Qu'est-ce que le
veille () code> utilisé pour?Il est utilisé comme retard entre l'envoi d'un paquet UDP et recevoir une réponse.
Cette solution qtime ne serait-elle pas échouée à minuit?
oui ça le ferait. Une meilleure solution serait une qwaitCondition ou quelque chose du genre.