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 ?
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