C'est justement la différence entre un signal et un événement :
- un signal (emit CeciCela) est exécuté immédiatement, c'est l'équivalent d'un appel de fonction vers chacun des slots connectés à ce signal (*)
- un événement est d'abord posté dans la file d'attente de la queue d'événements et sera traité dès que l'application exécutera à nouveau la boucle d'événements, donc plus tard.
C'est d'ailleurs pour cette raison qu'existe la fonction
deleteLater() : si un objet monButton émet un signal 'clicked' qui lui même est connecté à un slot 'onButtonClicked' de maFenetre, je n'ai pas le droit de faire dans 'onButtonClicked' un 'delete monButton' : en effet, 'onButtonClicked' est appelé directement par monButton, donc quand on retournera de 'onButtonClicked', la pile d'exécution devrait continuer dans monButton ... qui vient d'être deleté => crash car on a corrompu la pile d'exécution.
La solution est d'utiliser 'monButton.deleteLater()' au lieu de 'delete monButton' : ça postera un événement dans la boucle d'événements qui sera traité après que la pile d'exécution soit sortie du traitement du signal monbutton, donc la pile d'exécution ne contiendra plus de référence à monButton.
(*) il y a une exception à cela: quand un signal est connecté à un slot d'un objet appartenant à autre thread: comme on n'a pas le droit d'aller 'taper' dans les objets d'un autre thread, c'est à la place un événement 'activer slot ceciCela' qui est alors ajouté dans la liste d'événement du thread différent. cf.
Qt::ConnexionType.
Partager