Que puis-je utiliser pour remplacer le sommeil et le sommeil dans mon application Qt?
Je suis de l'importation d'une partie de code existant dans mon application Qt et a remarqué une fonction de veille. Je vois que ce type de fonction n'a pas sa place dans la programmation des événements. Que dois-je faire à la place?
Mise à JOUR: Après réflexion et les commentaires, je dirais que la réponse est: l'appel du sommeil à l'extérieur de la principale de l'interface fil et si vous avez besoin d'attendre dans le thread GUI utilisation processEvents() ou une boucle, cela permettra d'éviter l'interface utilisateur graphique de congélation.
source d'informationauteur yan bellavance | 2009-12-23
Vous devez vous connecter pour publier un commentaire.
Il n'est pas assez, mais j'ai trouvé ça dans le Qt archives des listes de diffusion:
La méthode sleep de QThread est protégé, mais vous pouvez l'exposer de la sorte:
Puis il suffit d'appeler:
à partir de n'importe quel thread.
Cependant, une solution plus élégante serait de revoir votre code pour utiliser un QTimer - ce qui peut nécessiter l'enregistrement de l'état afin de savoir quoi faire lorsque la minuterie s'éteint.
Je ne recommande pas dormir dans un événement en fonction du système, mais si vous voulez ...
Vous pouvez utiliser un waitcondition, de cette façon, vous pouvez toujours interrompre le sommeil si nécessaire.
La raison pourquoi le sommeil est une mauvaise idée dans l'événement en fonction de programmation est parce que basée sur les événements de la programmation est en réalité d'une forme de non-multitâche préemptif. En appelant le sommeil, de vous prévenir de tout autre événement devient active et, par conséquent, le blocage de la transformation du fil.
Dans une réponse à la requête de scénario pour les paquets udp, envoyer la demande immédiatement et attendez la réponse. Qt a la bonne socket Api qui permettra de s'assurer que le support ne bloque pas lors de l'attente de l'événement. L'événement viendra où il vient. Dans votre cas, la QSocket::readReady signal est votre ami.
Si vous souhaitez planifier un événement pour un certain moment dans l'avenir, l'utilisation QTimer. Cela permettra d'assurer que d'autres événements ne sont pas bloqués.
Il n'est pas nécessaire de ventiler les manifestations à tous. Tout ce que j'avais à faire était d'appeler
QApplication::processEvents()
oùsleep()
a été et cela empêche l'interface utilisateur graphique de congélation.Je ne sais pas comment le QTs gérer les événements en interne, mais sur la plupart des systèmes au niveau le plus bas de la vie de l'application qui va comme ceci: le thread principal code est essentiellement une boucle (la boucle de message), dans lequel, à chaque itération, l'application appelle une fonction qui lui donne un nouveau message; en général, cette fonction est bloquante, c'est à dire si il n'y a pas de messages de la fonction ne retourne pas et l'application est arrêtée.
Chaque fois que la fonction retourne, l'application a un nouveau message sur le processus, qui a généralement des destinataire (la fenêtre à laquelle est envoyée), un sens (le code de message, par exemple, le pointeur de la souris a été déplacé) et quelques données supplémentaires (par exemple, la souris a été déplacé à coords 24, 12).
Maintenant, l'application doit traiter le message; l'OS ou le toolkit graphique habitude de le faire sous le capot, donc avec un peu de magie noire, le message est envoyé à son destinataire et que le gestionnaire d'événement est exécuté. Lorsque le gestionnaire d'événement renvoie, la fonction interne qui a appelé le gestionnaire d'événement renvoie, celui qui l'a appelé et ainsi de suite, jusqu'à ce que le contrôle revient à la boucle principale, qui va maintenant appelez à nouveau la magie de message de la récupération de la fonction pour obtenir un autre message. Ce cycle continue jusqu'à ce que l'application se termine.
Maintenant, j'ai écrit tout cela pour vous faire comprendre pourquoi le sommeil est mauvais dans un événement piloté par application de l'interface utilisateur: si vous remarquez, alors qu'un message est traité pas d'autres messages peuvent être traitésdepuis le thread principal est occupé de l'exécution de votre gestionnaire d'événements, qui, après tout, c'est juste une fonction appelée par la boucle de message. Donc, si vous faites votre gestionnaire d'événement de sommeil, aussi la boucle de message va dormir, ce qui signifie que l'application dans le temps de ne pas recevoir et de traiter tous les autres messages, y compris ceux qui font de votre fenêtre de repeindre, de sorte que votre application va chercher "accrocher" à partir du point de vue utilisateur.
Longue histoire courte: ne pas utiliser de sommeil, sauf si vous avez le sommeil pour un temps très court (quelques centaines de millisecondes au plus), sinon le GUI ne répond plus. Vous disposez de plusieurs options pour remplacer le sommeils: vous pouvez utiliser une minuterie (QTimer), mais il peut vous obliger à faire beaucoup de tenue de la comptabilité entre un événement de minuterie et de l'autre. Une alternative populaire est de lancer un thread de travail séparé: il suffit de gérer la communication UDP, et, étant séparé du thread principal, il ne causera aucun problème de sommeil lorsque cela est nécessaire. Évidemment, vous devez prendre soin de protéger les données partagées entre les threads avec les mutex et être prudent pour éviter les conditions de course et tous les autres types de problèmes qui se produisent avec le multithreading.