I’m frequently checking the statistics of this blog. I have found that a vast amount of visitors are finding my blog when they are searching for solution to the “undefined reference to vtable” error in QT. I thought it worts to write a summary about this error and the possible solutions.
Don’t panic!
Usually this error pops up when you have a moc compiler related error. The moc compiler is a QT compiler tool. QT is extending the C++ language by some macros and non C++ language elements like signals slots etc. In order to compile the QT programs with a C++ compiler, these files which contain non C++ elements need preprocessing. The moc compiler should find and process all header files which has QT specific stuff especially signals and slots.
First thing to try:
make clean
manually remove all generated files especially which has suspicious ‘moc’ in their names
if make didn’t do that
rm Makefile
qmake
make
OK if the problem still exist, check the project file (*.pro)
Make sure that all header files which contain classes with signals and slots are added to the HEADERS qmake variable. E.g.:
HEADERS += myheaderwithsignalsslots.h \
otherheaderwithsignalsslots.h
Make sure these header files are in the include path. You can add your include directory to the INCLUDEPATH qmake variable. E.g.:
INCLUDEPATH += . ./include
Now try to compile again:
make clean
manually remove all generated files especially which has suspicious ‘moc’ in their names
if make didn’t do that
rm Makefile
qmake
make
If the problem still exist, check the header file itself which contains the class in question. Make sure that the class is actually defined in a header file and not in a cpp!
Every class which has signals and slots has to be inherited from QObject directly or indirectly.
Right after the opening curly bracket you should include the Q_OBJECT macro. E.g.:
class ArthurCanvas : public QWidget
{
Q_OBJECT
…
If you have a class that is inherited from QObject but in this class you do not introduce new signals and/or slots you should not include the Q_OBJECT macro.
One more thing you can check if nothing helps. This will not solve the problem, but will help you to investigate. Check the Makefile that qmake generates:
rm Makefile
qmake
Open Makefile in a text editor and look for
compiler_moc_header_make_all:
and
compiler_moc_header_clean:
and the entries after these
They should have references related to your header file in question. E.g. if you had foo.h you should have moc_foo.cpp listed for compiler_moc_header_make_all. If it is not the case, than qmake did not find the header file or the header file has some problem and qmake thinks it does not need to be moc-ed…
Finally, I do not recommend to mess up with including moc generated stuff manually to your makefile unless you know what you are doing. If your project file is correct, qmake will generate a correct Makefile to you.
I hope these will help… Never forget your towel!