Question

wx (et wxPython) a deux événements qui me manquent dans PyQt:

  • EVT_IDLE qui est envoyé à une trame. Il peut être utilisé pour mettre à jour les différents widgets en fonction de l'état de l'application
  • EVT_UPDATE_UI qui est envoyé à un widget lorsqu'il doit être repeint et mis à jour afin que je puisse calculer son état dans le gestionnaire

PyQt semble ne pas en avoir, et le livre PyQt suggère d’écrire une méthode updateUi et de l’appeler manuellement. J'ai même fini par l'appeler à partir d'une minuterie une fois toutes les 0,1 seconde, afin d'éviter de nombreux appels manuels à partir de méthodes susceptibles de mettre à jour l'interface graphique. Est-ce que je manque quelque chose? Y a-t-il un meilleur moyen d'y parvenir?

Un exemple: j'ai une application simple avec un bouton Démarrer qui lance un traitement. Le bouton de démarrage ne doit être activé que lorsqu'un fichier a été ouvert à l'aide du menu. De plus, la barre d’état contient un widget permanent qui affiche des informations.

Mon application a les états suivants:

  1. Avant que le fichier ne soit ouvert (dans cet état, la barre d'état affiche quelque chose de spécial et le bouton de démarrage est désactivé)
  2. Le fichier a été ouvert et le traitement n'a pas démarré: le bouton de démarrage est activé, la barre d'état indique autre chose
  3. Le traitement est en cours: le bouton de démarrage indique maintenant "Arrêter" et la barre d'état indique la progression

Sous Wx, l’événement UI de mise à jour du bouton gérait son état: le texte qu’il contient et son activation, en fonction de l’état de l’application. Idem pour la barre d'état (ou j'utiliserais EVT_IDLE pour cela).

Sous Qt, je dois mettre à jour le bouton selon plusieurs méthodes pouvant affecter l’état, ou créer une méthode update_ui et l’appeler périodiquement dans une minuterie. Quelle est la méthode la plus "QT"?

Était-ce utile?

La solution

L'utilisation de EVT_UPDATE_UI dans wxWidgets semble mettre en évidence l'une des différences fondamentales dans la manière dont wxWidgets et Qt attendent des développeurs qu'ils gèrent les événements dans leur code.

Avec Qt, vous connectez des signaux et des logements entre des widgets dans l'interface utilisateur, en gérant soit la "logique applicative", dans chaque emplacement ou en le déléguant à une méthode dédiée. En règle générale, vous n'avez pas à modifier séparément chaque widget de votre interface graphique, car toutes les demandes de repeinte sont placées dans la file d'attente des événements et livrées lorsque le contrôle revient à la boucle d'événements. Certains événements de peinture peuvent même être fusionnés pour plus d’efficacité.

Ainsi, dans une application Qt normale où les signaux et les emplacements sont utilisés pour gérer les changements d'état, il n'est généralement pas nécessaire de disposer d'un mécanisme inactif permettant de surveiller l'état de l'application et de mettre à jour les widgets, car ces mises à jour doivent se produire automatiquement.

Il vous faudrait en dire un peu plus sur ce que vous faites pour expliquer pourquoi vous avez besoin d'un équivalent à cet événement dans Qt.

Autres conseils

J'enverrais des signaux Qt pour indiquer les changements d'état (par exemple, fileOpened, processingStarted, processingDone). Les emplacements dans les objets qui gèrent le bouton de démarrage et le widget (ou les sous-classes) de la barre d'état peuvent être connectés à ces signaux, plutôt que "interrogation". pour l'état actuel dans un événement inactif.

Si vous souhaitez que le signal soit différé plus tard dans la boucle d'événement plutôt qu'immédiatement (par exemple, il faudra un peu de temps pour faire quelque chose), vous pouvez utiliser un "en file d'attente". connexion signal-slot plutôt que le type normal.

http://doc.trolltech.com/4.5/signalsandslots.html#signals

Le type de connexion est un paramètre facultatif de la fonction connect (): http://doc.trolltech.com/4.5/qobject.html#connect, http://doc.trolltech.com/4.5/qt.html# ConnectionType-enum

Autant que je sache, EVT_IDLE est envoyé lorsque la file d'attente des messages d'application est vide. Il n’existe pas d’événement de ce type dans Qt, mais si vous avez besoin d’exécuter quelque chose dans Qt alors qu’il n’y a aucun événement en attente, vous devez utiliser QTimer avec un délai d’attente de 0.

En général, la méthode la plus répandue consiste à mettre à jour le bouton / la barre d’outils selon les besoins dans les fonctions nécessitant la mise à jour, ou à consolider certaines des fonctionnalités et à appeler directement cette fonction lorsque le programme en a besoin (par exemple, updateUi. fonction).

Vous devez savoir que dans Qt, la modification d'un attribut d'un élément Ui ne provoque pas de rafraîchissement immédiat, mais met en file d'attente un rafraîchissement dans le système d'événements et que plusieurs appels de rafraîchissement sont compressés dans un si possible.

En ce qui concerne les multiples modifications relatives à l'état, consultez cet article de blog à propos d'un prochain ajout à Qt, espérons-le, permettant de gérer plus facilement les états. Il semble que cela résoudrait un grand nombre de vos plaintes, car dans vos fonctions multiples, vous pouvez simplement faire la transition de la variable d'état et les autres parties de l'interface utilisateur doivent être mises à jour pour correspondre. Ce n'est pas positif, cela fera partie de la prochaine version de Qt (bien que je parie dessus, ou quelque chose de similaire), et je n'ai aucune idée de la proximité avec laquelle PyQt suit les versions de Qt. Ou bien, vous pouvez utiliser le concept et créer votre propre classe pour suivre l’état au besoin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top