Au secours, mes slots ne fonctionnent pas
Par lud42fr le vendredi, juin 22 2007, 22:20 - Documentation - Lien permanent
Une liste de points à appliquer pour réussir ses connexions entre signaux et slots.
Version : Qt3, Qt4
Auteur : Ludo (lud42fr)
Don't panic
Premier diagnostic:
Lorsque qu'un slot n'est pas appelé, il y a trois solutions :
- Je n'ai pas lu la doc et je le regrette
- Le signal n'est pas émis et ce document est trop général pour répondre à ce cas !
- Le slot est mal connecté et le chapitre suivant décrit les bons réflexes
Premiers réflexes:
- Rester détendu
- Vérifier sur la console les messages d'erreur
- Vérifier que la classe débute par la macro Q_OBJECT
- Vérifier la syntaxe de la connexion
- Vérifier que les signatures sont correctes
- Vérifier que la signature du signal est la même que celle du slot
L'action au ralenti
- Mettre un grand coup de latte dans l'UC, ça ne corrige pas le problème, mais ça permet de l'aborder détendu.
- Vérifier sur la console (voir activer la console en annexe A), que Qt ne signale pas une ou plusieurs erreurs concernant la connexion à l'exécution (les erreurs de connexion n'apparaissent qu'a l'exécution)
Les messages peuvent prendre plusieurs formes et tenir sur plusieurs lignes, mais ont tous en commun, le fait de débuter par Object::connect: Par exemple l'affichage pour une seule connexion défaillante:
Object::connect: Parentheses expected, slot MainWindow::'' Object::connect: (sender name: 'test')'' Object::connect: (receiver name: 'WindowMain')
- Vérifier que la classe débute par la macro Q_OBJECT :
La classe qui contient le slot (ou le signal d'ailleurs) doit débuter par la macro Q_OBJECT. Ce mot clé est repéré par le meta-object-compiler (moc) et permet de générer le code nécessaire à la recherche et à l'identification des slots, code qui sera utilisé par la méthode connect. Ex:
class maClasse : public QObject { Q_OBJECT public: };
- Vérifier dans le code, que la syntaxe de la connexion est correcte :
pour cela on rappelle la méthode connect (la plus courante) :
connect(pointeur_sur_l_objet_emetteur, SIGNAL(signature_du_signal),pointeur_sur_l_objet_receveur, SLOT(signature_du_slot));
A noter qu'il est possible de connecter un signal à un autre signal, le principe reste le même :
connect(pointeur_sur_l_objet_emetteur, SIGNAL(signature_du_signal_emetteur),pointeur_sur_l_objet_receveur,SIGNAL(signature_du_signal_receveur));Passons pointeur_sur_l_objet_emetteur et pointeur_sur_l_objet_receveur, trivial Par contre attardons nous sur la signature d'une méthode : par exemple :
class maclasse { void ma_methode(int argument1,char* argument2); };
la signature de ma_methode est : ma_methode (int,char*)
Si on généralise une signature de méthode c'est : le_nom_de_la_methode ( le_type_de arg1,...,le_type_de_argN)
- Vérifier que les signatures sont correctes (ça s'appelle enfoncer le clou !)
Donc on ne met pas le nom des arguments, juste leur type
connect(a, SIGNAL(mon_signal(int)),b, SLOT(mon_slot(int argument)));
Et on met encore moins de valeurs
connect(a, SIGNAL(mon_signal(42)),b, SLOT(mon_slot(int)));
- Vérifier que la signature de mon signal est la même que celle de mon slot :
C'est a dire que mon slot a les mêmes types d'arguments et le même nombre d'arguments que mon signal
note: il est possible que le slot ait moins d'arguments que le signal, mais dans un soucis de clarté, ce doc fait l'impasse la dessus !
- Vérifier qu'il n'y a pas faute de copier/coller, de parenthèses ou de caractères en trop dans SIGNAL() et SLOT().
En effet SIGNAL() et SLOT() sont des macros qui, entres autres, convertissent leur contenu en chaine de caractère. Dans ce cas une erreur de syntaxe, ne provoque pas d'erreur à la compilation.
Ca ne marche toujours pas :
Alors une âme charitable pourra sûrement se pencher sur le problème (forum)
Annexes
Activer la console
La console est la sortie que Qt privilégie pour afficher ses messages d'erreurs.
- Sous les systèmes un*x like, cette dernière est active par défaut, et pour visualiser les traces il suffit, d'exécuter son application depuis un shell ou se référer a la doc de son IDE afin de capturer la sortie standard.
- Sous les systèmes win32 il faut ajouter dans le fichier .pro du projet :
CONFIG += console
puis recompiler l'application.
Les traces seront alors affichées dans une console ouverte en parallèle de l'application si celle-ci n'est pas lancée depuis la ligne de commande. Dans ce dernier cas, les traces sont affichées dans la console ayant servi à l'appel
Commentaires