J'utilise Qt Creator 2.0.1 avec Qt 4.7.0 (32 bits) sur Windows 7 Ultimate 32 bits.
Considérez le code suivant, qui est un minimum pour produire l'erreur:
class T : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
T() {}
QRectF boundingRect() const {return QRectF();}
void Paint(QPainter *Painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) {}
};
int main()
{
T t;
return 0;
}
Le fragment de code ci-dessus provoque les erreurs de l'éditeur de liens suivantes:
Dans la fonction "T":
référence non définie à "vtable pour T"
référence non définie à "vtable pour T"
Dans la fonction `~ T ':
référence non définie à "vtable pour T"
référence non définie à "vtable pour T"
Si je commente la ligne qui contient Q_OBJECT
, il compile très bien. J'ai besoin de signal et de slots avec QGraphicsItem
donc j'ai besoin de Q_OBJECT
.
Quel est le problème avec le code? Merci.
C'est parce que l'unité générée par MOC n'est pas incluse dans le processus de liaison. Ou peut-être que ce n'est pas du tout généré. La première chose que je ferais est de mettre la déclaration de classe dans un fichier d'en-tête séparé, peut-être que le système de construction n'analyse pas les fichiers d'implémentation.
Une autre possibilité est qu'une fois la classe en question n'appartenait pas au système de méta-objet Qt (c'est-à-dire qu'elle n'avait pas Q_OBJECT ou qu'elle n'héritait peut-être pas du tout de QObject), donc qmake doit être réexécuté pour créer le règles nécessaires pour le MOC. Le moyen le plus simple de forcer l'exécution de qmake consiste à apporter des modifications insignifiantes au fichier de projet pour mettre à jour son horodatage, comme l'ajout puis la suppression d'un espace blanc. Ou, si vous utilisez Qt Creator, sélectionnez simplement "Exécuter qmake" dans le menu contextuel du projet.
Si vous souhaitez définir une sous-classe QObject
dans un fichier source, vous devez ajouter la ligne
#include "file.moc"
à un moment donné après la définition de votre classe où le nom du fichier source était file.cpp. Vous devrez bien sûr réexécuter qmake
pour que la règle appropriée pour exécuter moc
soit ajoutée au Makefile.
Ce n'est que dans un fichier d'en-tête que la présence de Q_OBJECT
dans une définition de classe provoque l'appel de moc
. S'il s'agit d'un fichier source, vous avez besoin de cette ligne supplémentaire pour forcer l'utilisation de moc
.
Je suis sûr qu'une question similaire a déjà été posée, mais je ne l'ai pas trouvée.
Mettez vos classes Q_OBJECT dans des fichiers séparés. C'est un .h et un .cpp pour chaque classe. Les macros de méta-objets de Qt sont un peu difficiles à cet égard.
En outre, vous pouvez utiliser QGraphicsObject pour votre objectif. Vous fait gagner du temps là-bas.
Edit: je vois que vous utilisez Creator. Utilisez sa fonction Nouvelle classe C++ dans Nouveau fichier ou projet pour créer le fichier de la "bonne façon" :)
Voici du code de travail ajouté avec tous les correctifs fournis dans d'autres questions (compilation propre et aide à ces correctifs):
#include <QGraphicsItem>
class T : public QObject, public QGraphicsItem
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem) //Required.
public:
T() {}
QRectF boundingRect() const {return QRectF();}
void Paint(QPainter *Painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) {}
};
int main(int argc, char *argv[])
{
T *t = new T;
return 0;
}
#include "main.moc" // Required.
Donc, crédit réel à Troubadour et serge_gubenko
il y a deux ou trois choses à regarder:
ci-dessous est un exemple:
t.h:
class T : public QObject, public QGraphicsItem
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
public:
T();
QRectF boundingRect() const;
void Paint(QPainter *Painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
t.cpp:
T::T() {}
QRectF T::boundingRect() const
{
return QRectF();
}
void T::Paint(QPainter *Painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(Painter);
Q_UNUSED(option);
Q_UNUSED(widget);
}
J'ai essayé de compiler le code ci-dessus et je n'ai eu aucun problème avec.
j'espère que cela vous aide,