Qt: No matching function for call to connect

Publié dans C / C++ | Marqué avec , ,
Share

Qt permet de relier facilement entre elle des classes héritant de QObject avec des liens signaux / slots. Voici un petit exemple de connexion.

class OtherQObject : public QObject
{
Q_OBJECT
public:
    OtherQObject();

signal:
    void aSuperSignal();
};
class MyQObject : public QObject
{
Q_OBJECT
public:
    MyQObject();

public slots:
    void myGreatMethod();
};
MyQObject *myClass;
OtherQObject *otherClass;
connect(otherClass, SIGNAL(aSuperSignal()), myClass, SLOT(myGreatMethod());

A de nombreuses reprises, il m’est arrivé d’être confronté à l’erreur suivante (ou similaire) : « No matching function for call to connect ». Plus précisément :

error: no matching function for call to ‘mainWindow::connect(MyQObject *&, const char [38], OtherQObject *&, const char [30])’
note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
note: bool QObject::connect(const QObject*, const char*, const char*, Qt::Connection

J’aimerai lister ici quelques causes possibles de ce type d’erreur. Un article sans fioriture, avec l’information brute de chez brute, mais qui sait, peut-être aurais-je un jour l’envi de peaufiner un petit peu ce bric à brac ?


abstract-connections

Eh, il faut un pointeur !

Lors de la connexion, la classe émettant le signal doit être un pointeur ! Il est vite arrivé d’oublier l’esperluette dans certains cas…

MyQObject *myClass;
QTimer timer;
connect(&timer, SIGNAL(timeout()), myClass, SLOT(myGreatMethod());

Forward declaration

Pour connecter un QObject qui a été forward declared (class MyQObject dans le .h de l’utilisateur), il ne faut pas oublier d’inclure réellement le .h du QObject (dans le .cpp de l’utilisateur).

Namespace

Si votre signal/slot transporte des éléments sous namespaces, avant Qt 5 il faut toujours mettre le nom complet dans les déclarations des signaux / slots, et lors de la connexion. Même si cela semble inutile… En effet, Qt transforme la signature des signaux et des slots en string et fait une bête comparaison d’une chaîne de caractère. Étonnamment, « MyClass » et « MyNamespace::MySpace » ne sont plus très égaux en terme de chaîne de caractères…
Je ne sais plus quel est le message d’erreur qui s’affiche, mais il doit y ressembler.

Bien étiqueter…

Certaines classes ne sont pas transportables directement via signal / slot, notamment les listes, les maps… Il faut les déclarer préalablement à l’aide de la macro Q_DECLARE_METATYPE et de la méthode qRegisterMetaType. Je sais que les deux ne sont pas toujours utiles, mais n’ayant pas encore compris pourquoi, j’utilise toujours les deux.
Je ne sais plus quel est le message d’erreur qui s’affiche, mais il doit y ressembler.

// Simple object
Q_DECLARE_METATYPE(PhysicalDriverState)
// List and map
typedef QHash<ulong,int> myHash;
typedef QList<ulong> myList;
Q_DECLARE_METATYPE(myHash)
Q_DECLARE_METATYPE(myList)

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);

  // Simple object
  qRegisterMetaType<PhysicalDriverState>();
  // List and map
  qRegisterMetaType< QHash<ulong,int> >("QHash<ulong,int>");
  qRegisterMetaType< QList<ulong> >("QList<ulong>");

  return a.exec();
}

One Response to Qt: No matching function for call to connect

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *