Ich verwende Qt Creator 2.0.1 mit Qt 4.7.0 (32 Bit) unter Windows 7 Ultimate 32 Bit.
Betrachten Sie den folgenden Code, der das Minimum darstellt, um den Fehler zu erzeugen:
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;
}
Das obige Codefragment verursacht die folgenden Linker-Fehler:
In der Funktion 'T':
undefinierter Verweis auf `vtable for T '
undefinierter Verweis auf `vtable for T '
In der Funktion ~ T:
undefinierter Verweis auf `vtable for T '
undefinierter Verweis auf `vtable for T '
Wenn ich die Zeile auskommentiere, die Q_OBJECT
Enthält, wird sie korrekt kompiliert. Ich brauche ein Signal und Slots mit QGraphicsItem
, also brauche ich Q_OBJECT
.
Was ist los mit dem Code? Vielen Dank.
Dies liegt daran, dass die von MOC generierte Einheit nicht in den Verknüpfungsprozess einbezogen wird. Oder vielleicht wird es gar nicht erzeugt. Das erste, was ich tun würde, ist, die Klassendeklaration in einer separaten Header-Datei abzulegen. Vielleicht scannt das Build-System keine Implementierungsdateien.
Eine andere Möglichkeit besteht darin, dass die betreffende Klasse nicht zum Qt-Metaobjektsystem gehörte (dh, sie hatte kein Q_OBJECT oder erbte möglicherweise überhaupt kein QObject). Daher muss qmake erneut ausgeführt werden, um das zu erstellen notwendige Regeln für MOC. Die einfachste Möglichkeit, die Ausführung von qmake zu erzwingen, besteht darin, geringfügige Änderungen an der Projektdatei vorzunehmen, um den Zeitstempel zu aktualisieren, z. B. Leerzeichen hinzuzufügen und anschließend zu entfernen. Wenn Sie Qt Creator verwenden, wählen Sie einfach im Kontextmenü des Projekts die Option "qmake ausführen".
Wenn Sie eine Unterklasse QObject
in einer Quelldatei definieren möchten, müssen Sie die Zeile hinzufügen
#include "file.moc"
irgendwann nach Ihrer Klassendefinition war der Name der Quelldatei file.cpp. Sie müssen qmake
natürlich erneut ausführen, damit die entsprechende Regel zum Ausführen von moc
zum Makefile hinzugefügt wird.
Nur wenn in einer Header-Datei das Vorhandensein von Q_OBJECT
in einer Klassendefinition bewirkt, dass moc
aufgerufen wird. Wenn es sich um eine Quelldatei handelt, benötigen Sie diese zusätzliche Zeile, um die Verwendung von moc
zu erzwingen.
Ich bin sicher, dass eine ähnliche Frage schon einmal gestellt wurde, aber ich konnte sie nicht finden.
Platzieren Sie Ihre Q_OBJECT-Klassen in separaten Dateien. Das ist eine .h und eine .cpp für jede Klasse. Qts Meta-Objekt-Makros sind in dieser Hinsicht ziemlich wählerisch.
Sie können auch QGraphicsObject für Ihren Zweck verwenden. Spart Ihnen dort etwas Zeit.
Bearbeiten: Ich sehe, dass Sie Creator verwenden. Verwenden Sie die Funktion New C++ Class in New File oder Project, um die Datei "richtig" zu erstellen :)
Hier wird Arbeitscode mit allen in anderen Fragen bereitgestellten Fixes hinzugefügt (Versuchtes sauberes Kompilieren und diese Fixes helfen):
#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.
Also wirklicher Dank an Troubadour und serge_gubenko
es gibt ein paar Dinge zu sehen:
unten ist ein Beispiel:
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);
}
Ich habe versucht, den obigen Code zu kompilieren und hatte keine Probleme damit.
hoffe das hilft, grüße