IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ Qt 5 et erreurs courantes

FAQ Qt 5 et erreurs courantesConsultez toutes les FAQ

Nombre d'auteurs : 1, nombre de questions : 16, dernière mise à jour : 20 septembre 2021 

 
OuvrirSommaireMessages d'erreur…… à l'exécution
précédentsommairesuivant
 
 

Rappel : ce message est émis dans l'onglet du bas intitulé « Sortie de l'application » dans Qt Creator. Il est obtenu pendant l'exécution de la ligne connect() correspondante utilisant les macros SIGNAL/SLOT lorsque les conditions qui suivent ne sont pas remplies.

Depuis Qt 5/C++11, l'utilisation de ces macros est dépréciée et il est vivement conseillé d'utiliser la nouvelle syntaxe utilisant des pointeurs sur fonctions (membres) :

Notez l'absence de parenthèses, il ne s'agit pas d'appels de fonctions, nous ne faisons que passer les adresses des fonctions (ici membres).

 
Sélectionnez
connect(emetteur, &ClasseEmetteur::nomDuSignal,
        receveur, &ClasseReceveur::nomDuSlot);

Cette syntaxe présente les avantages de vérifier cette erreur à la compilation plutôt que durant l'exécution, et d'autoriser la conversion implicite des paramètres du signal vers ceux du slot.

Je vous conseille la lecture des articles suivants : Les signaux et slots dans Qt 5.4, Les signaux et slots avec Qt 5, de nouvelles possibilités et Differences between String-Based and Functor-Based Connections.

Ce message peut être dû à plusieurs raisons.

  • Une classe qui utilise les signaux et slots doit :

    • hériter de QObject, directement ou par le biais de l'une de ses classes dérivées (par ex. QWidget) ;
    • utiliser la macro Q_OBJECT ;
  • Un slot doit être déclaré dans la classe comme ceci à l'aide du mot-clé slots ; un signal avec le mot-clé signals :
    (Non obligatoire si vous utilisez la nouvelle syntaxe apparue avec Qt 5 présentée au début de sujet.)

     
    Sélectionnez
    public slots: // public, protected ou private
        void nomDuSlot(/* éventuels paramètres */);
    signals: // = public depuis Qt 5, protected avant
        void nomDuSignal(/* éventuels paramètres */);
  • Suite à une faute de frappe, il se peut que vous ayez mal orthographié le nom du signal/slot (casse incluse : clicked est différent de Clicked). Vérifiez donc la bonne concordance entre sa déclaration (dans la documentation de la classe ou votre .h) et son utilisation dans le connect(…); ;
  • Vous avez tout simplement oublié de le déclarer dans votre classe.

Commencez donc par vérifier ces éléments, et corrigez-les si besoin. (Notamment pour le rajout de la macro Q_OBJECT, prenez soin d'exécuter qmake juste après. Il se peut que vous ayez à nettoyer (clean) et recompiler votre projet [menu « Compiler » dans Qt Creator] pour que la modification prenne effet.)

Si l'erreur persiste, deux autres cas peuvent se présenter.

1) Mauvaise concordance receveur/slot ou de l'émetteur/signal

Pour rappel la fonction connect(), dans son utilisation la plus classique, va connecter le signal d'une instance emetteur au slot d'une instance receveur :

 
Sélectionnez
connect(emetteur, SIGNAL(nomDuSignal(/* éventuels types */)),
        receveur, SLOT(nomDuSlot(/* éventuels types */)) );
à chaque émission du signal :
  emit emetteur->nomDuSignal(/* valeurs transmises */),
sera exécuté :
  receveur->nomDuSlot(/* valeurs reçues depuis celles transmises */)

il faut donc que le signal nomDuSignal() soit membre de la classe de emetteur, et que le slot soit nomDuSlot() de la classe de receveur.

Une erreur classique de débutant consiste à faire :

 
Sélectionnez
connect(button,   SIGNAL(clicked()),
        lineEdit, SLOT(nomDuSlot()) );

nomDuSlot() étant un slot de votre classe, alors que lineEdit est une instance de la classe QLineEdit : la classe QLineEdit ne possédant évidemment pas votre slot, vous obtenez cette erreur No such slot QLineEdit::nomDuSlot(), car lineEdit->nomDuSlot() n'existe pas, nous voulons this->nomDuSlot().

C'est le pointeur vers l'instance de votre classe (à savoir this) qu'il vous faut fournir en 3e argument :

 
Sélectionnez
connect(button, SIGNAL(clicked()),
        this,   SLOT(nomDuSlot()) );

Il vous est possible dans ce cas d'omettre ce 3e argument, this sera utilisé par défaut :

 
Sélectionnez
connect(button, SIGNAL(clicked()), SLOT(nomDuSlot()) );
Nouvelle syntaxe
Sélectionnez
connect(button, &QPushButton::clicked, this, &VotreClasse::nomDuSlot);

2) Tentative erronée de passer des arguments ou mention des noms des paramètres

Comme rappelé dans le 1) dans les commentaires du premier code, vous devez écrire entre parenthèses les types que prennent les signaux et slots.

Et seulement les types, pas les noms des paramètres ! Par ex. mentionner value dans SLOT(votreSlot(int value)) est faux.
Attention également à ne pas confondre nouvelle et ancienne syntaxe. Dans l'ancienne syntaxe, NomClasse:: ne doit pas apparaître devant les noms du signal et du slot.

Vous ne pouvez pas ajouter vos propres arguments sur cette ligne, les seuls passés sont ceux transmis depuis le signal émis vers le slot. Le code suivant, qui a pour volonté de fixer le texte suite à l'appui sur le bouton, est par conséquent faux :

 
Sélectionnez
connect(button,   SIGNAL(clicked()),
        lineEdit, SLOT(setText("Texte")) );

et vous donne le message No such slot QLineEdit::setText("Texte").

Veuillez consulter le sujet Comment passer des paramètres à mon slot lors du connect() ? pour savoir comment procéder.

À voir également

Mis à jour le 21 février 2020  par Winjerome

Rappel : ce message est émis dans l'onglet du bas intitulé « Sortie de l'application » dans Qt Creator. Il est obtenu pendant l'exécution de la ligne connect() correspondante utilisant les macros SIGNAL/SLOT lorsque les conditions qui suivent ne sont pas remplies.

Depuis Qt 5/C++11, l'utilisation de ces macros est dépréciée et il est vivement conseillé d'utiliser la nouvelle syntaxe utilisant des pointeurs sur fonctions (membres) :

Notez l'absence de parenthèses, il ne s'agit pas d'appels de fonctions, nous ne faisons que passer les adresses des fonctions (ici membres).

 
Sélectionnez
connect(emetteur, &ClasseEmetteur::nomDuSignal,
        receveur, &ClasseReceveur::nomDuSlot);

Cette syntaxe présente les avantages de vérifier cette erreur à la compilation plutôt que durant l'exécution, et d'autoriser la conversion implicite des paramètres du signal vers ceux du slot.

Je vous conseille la lecture des articles suivants : Les signaux et slots dans Qt 5.4, Les signaux et slots avec Qt 5, de nouvelles possibilités et Differences between String-Based and Functor-Based Connections.

Cette erreur signifie que dans la connexion que vous avez effectuée, les paramètres du slot ne sont pas compatibles avec ceux émis par le signal. Et vous pouvez le voir dans la partie qui suit ce message et mentionne les éléments impliqués.

Par exemple, un signal void nomDuSignal(); ne pourra pas transmettre l'int qu'attendrait un slot void nomDuSlot(int);.
Pour connecter un tel slot, vous devrez avoir un signal avec une forme proche de void nomDuSignal(int);, transmettant un int.

Pour rappel la fonction connect(), dans son utilisation la plus classique, va connecter le signal d'une instance emetteur au slot d'une instance receveur :

 
Sélectionnez
connect(emetteur, SIGNAL(nomDuSignal(/* éventuels types */)),
        receveur, SLOT(nomDuSlot(/* éventuels types */)) );
à chaque émission du signal :
emit emetteur->nomDuSignal(/* valeurs transmises */),
sera exécuté :
receveur->nomDuSlot(/* valeurs reçues depuis celles transmises */)

De ce fait, pour garantir une bonne réception des valeurs depuis le slot, vous devez vous assurer que le signal sera bel et bien capable de les transmettre.

Si votre souhait n'est pas de transmettre ces valeurs depuis le signal, mais depuis des variables ou valeur littérales au niveau de la connexion, rendez-vous dans le sujet Comment passer des paramètres à mon slot lors du connect() ?.

Créé le 24 octobre 2019  par Winjerome
précédentsommairesuivant
 
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2020 Winjerome. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.