Q_OBJECT throwing 'undefined vtable error reference'

I am using Qt Creator 2.0.1 with Qt 4.7.0 (32 bit) on Windows 7 Ultimate 32 bit.

Consider the following code, which is the minimum for an error to occur:

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; } 

The above code snippet causes the following linker errors:

In the `T 'function:

undefined reference to `vtable for T '

undefined reference to `vtable for T '

In the `~ T 'function:

undefined reference to `vtable for T '

undefined reference to `vtable for T '

If I comment out the line containing Q_OBJECT , it compiles fine. I need signal and slots with QGraphicsItem , so I need Q_OBJECT .

What is wrong with the code? Thank.

+49
c ++ qt vtable linker-errors
Jan 23 2018-11-11T00:
source share
5 answers

This is because the unit generated by the MOC is not included in the binding process. Or maybe it is not generated at all. The first thing I would like to do is put the class declaration in a separate header file, perhaps the build system does not scan implementation files.

Another possibility is that the class in question once did not belong to the Qt meta-object system (that is, it did not have Q_OBJECT or, possibly, did not inherit from QObject at all), so qmake needs to be run again in order to create the necessary rules for MOC. The easiest way to get qmake to start is to make minor changes to the project file to update its timestamp, such as adding and removing some space. Or, if you are using Qt Creator, simply select “Run qmake” from the project’s context menu.

+95
Jan 23 '11 at 14:33
source share

If you want to define a QObject subclass in the source file, you need to add the line

 #include "file.moc" 

at some point after defining your class, where the name of the source file was file.cpp. You will need to restart qmake , of course, so that the corresponding rule to run moc added to the Makefile.

Only if in the header file the presence of Q_OBJECT in the class definition causes moc to be called. If this is the source file, you will need this extra line to force the use of moc .

I am sure that a similar question was asked before, but I could not find it.

+20
Jan 23 '11 at 3:45 a.m.
source share

Here is the working code added with all the fixes contained in other issues (clean compilation and these fixes fixed):

 #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. 

So, the real loan is Troubadour and serge_gubenko

+5
Jan 23 2018-11-21T00:
source share

Put the Q_OBJECT classes in separate files. This is one .h and one .cpp for each class. In this regard, Qt meta tag macros look disgusting.

Alternatively, you can use QGraphicsObject for your purpose. Saves you some time there.

Edit: I see that you are using Creator. Use the new C ++ class function in New File or Project to create the file in the “right way” :)

+4
Jan 23 2018-11-11T00:
source share

There are a few things to look at:

  • Add QT + = gui to your pro file
  • Make sure that you define the classes derived from QObject only in your header files (edit: as specified in Troubadour, this is not required).
  • Add Q_INTERFACES (QGraphicsItem) to your T class declaration
Below is an example

:

th:

 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); } 

I tried compiling the code above and had no problems with it.

hope this helps, believes

+3
Jan 23 2018-11-11T00:
source share



All Articles