88

I inherited a class from QObject :

class Parent: public QObject
{
    Q_OBJECT
    QObject* cl;

public:
    Parent(QObject *parent=0):QObject(parent) {
        cl = NULL;
    }

    QObject* getCl() const {
        return cl;
    }
    void setCl(QObject *obj) {
        cl = obj;
    }
};

But when I write :

Parent ev;

I get the following error:

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Parent::metaObject(void)const " (?metaObject@Parent@@UBEPBUQMetaObject@@XZ)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" (?qt_metacast@Parent@@UAEPAXPBD@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __thiscall Parent::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Parent@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
Vic Vuci
  • 6,993
  • 6
  • 55
  • 90
Mohsen Zahraee
  • 3,309
  • 5
  • 31
  • 45
  • Editing .vcxproj file worked for me... check if all the .h or .hh files are in QtMoc tag: ; Other things I already checked. – lRadha Aug 28 '23 at 17:20

27 Answers27

84

You should delete the debug folder of your application and run it again to correct this problem.

Mohsen Zahraee
  • 3,309
  • 5
  • 31
  • 45
  • 8
    I'm having the same issue. Deleting the debug folder didn't help. Any more ideas? – Vern Jensen Mar 27 '13 at 00:22
  • 2
    @Vern Jensen, check for `Q_OBJECT` macro, then rebuild, then delete debug/release folder (to delete all moc files) and rebuild again. One of this should help. – SpongeBobFan Jul 03 '13 at 06:26
  • 20
    removal of Q_OBJECT macro from the class, save and adding Q_OBJECT again worked for me when using the QT5 Plugin for VS 2012 – Beachwalker Dec 16 '13 at 10:43
  • This fixed my issue too. But why and how? Anyone please explain. Thanks! – Nayan Soni Feb 10 '17 at 07:59
  • 7
    I was having the same issue for a class project. I found that flat out removing `Q_OBJECT` macro fixed my problem. No idea why. But if I put it back I receive the same 3 unresolved errors. I fixed that problem by including the new classes inside of the `.pro` file for QT and the `cmakelists.txt` file I'm using. Once I included the header and the cpp files the code worked with `QObject`. – Callat Feb 27 '17 at 04:44
  • Methods like metaObject(), qt_metacall(), qt_metacast(), etc, are defined in the generated moc_ files. So the cause of the unresolved external symbol error is that the moc_ files are not compiled/linked to the project. If, in Visual Studio, deleting and reinserting Q_OBJECT does not work, check that the moc_ files are correctly generated and included in the project. – Marc Jun 26 '20 at 08:49
  • I had the same issue with a CMake project on Visual Studio. Like @Callat removing Q_OBJECT macro works but its not good. Turns out that I forgot to add the header file to the cmakelists.txt , thus I think the MOC was not run on it. Just adding the header file to cmakelist is enough. – qwark Jun 21 '23 at 12:20
68

If you're using Visual Studio, delete the line Q_OBJECT from the header file, save the file, put Q_OBJECT back into the header file, save the file again. This should generate the moc_* file and should build and link correctly.

Melebius
  • 6,183
  • 4
  • 39
  • 52
MPicazo
  • 691
  • 5
  • 9
  • 3
    None of the other solutions worked for me but this did! Thanks! ;) – zeFree Dec 05 '14 at 11:14
  • 5
    If you're using CMake, ensure that you have `set(CMAKE_AUTOMOC ON)` – Matt Jan 06 '17 at 16:22
  • 2
    this answer should also be noted as a valid answer ! – Adiel Yaacov Apr 24 '17 at 13:21
  • 3
    Woks for me (VS2017), thanks. Compiles with "Q_OBJECT" commented out, does not compile if restored. Does not inspire confidence in Qt. I thought the "Q_OBJECT" macro was necessary? – Pierre Feb 22 '19 at 17:12
  • I'm also with VS 2017. The following happens for me: I added AUTOMOC to my CMakeLists. That made my compiler choke on `public signal:` which it didn't previously. Still, I have the linker error whenever `Q_OBJECT` is in the code and a runtime error saying my custom class doesn't define a type otherwise. – starturtle May 28 '20 at 08:41
37

I noticed some answers are based on Visual Studio.

This answer is based on Qt Creator.

Unlike the name suggest, Rebuild Project will not wipe out everything and build from scratch. If you recently added QObject (and/or Q_OBJECT) to your class, you'll have to run qmake again, e.g.

  1. Clean Project
  2. Run qmake
  3. Build Project

This is because, by default, qmake only runs when you do significant changes to your solution like adding new source files or modify the .pro file. If you make edits to an existing file, it doesn't know it needs to run qmake.

As a fall back, to brute force Qt to build everything from scratch, delete the Debug or Release folder.

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
  • 1
    Brilliant! Worked for me. "Run qmake" is the key step. Q_OBJECT is necessary if you're going to use slots. – Pierre Sep 24 '18 at 13:12
13

So the issue was I needed the Qt MOC compiler to compile my .h file. This is required for any classes that extend QObject or one of its children. The fix involed (for me) right-clicking on the header file, choosing Properties, and setting the Item Type to "Qt MOC Input", then hitting "Compile" on the header, and then adding the resulting moc_myfilename.cpp file to my project.

Vern Jensen
  • 3,449
  • 6
  • 42
  • 59
  • Where exactly do you find this "properties"? In Qt Creator I do not see anything like this on right click. – Horst Walter Jul 19 '13 at 17:17
  • 1
    This is in XCode, right-clicking on the file listed in the "Navigator" view (the list of files your project uses). – Vern Jensen Jul 30 '13 at 18:14
  • 1
    This is possible in Visual Studio as well, but someone else would have to tell you exactly how to configure it there. (I'm sure you can find the answer on Qt's website.) – Vern Jensen Jul 30 '13 at 18:22
  • Also have the problem in QtCreator 3.1.0 (opensource). My QtObject derived class is in main.cpp. I cannot see any moc_*.* files in debug folder. Does that mean, I am forced to add the QtObject derived class into a header file to get it working? – BitTickler May 14 '14 at 15:38
  • 1
    For giggles, I added a header file and a .cpp file and moved my QtObject derived class into it, then also had to #include in the header file and suddenly it worked. Those things should really be documented somewhere.... – BitTickler May 14 '14 at 15:51
  • They should. This is incredibly stupid. I just spent the whole day trying to figure out... – Aros May 23 '15 at 16:44
  • this is whar qmake is supposed to do for you – Valentin H May 31 '18 at 20:41
  • 3
    Worked for me, except that the Type was "Custom Build Tool" instead of "Qt MOC Input". I'm using Visual Studio 2017. – Captain Normal Oct 19 '18 at 11:38
  • @CaptainNormal after specifying the Custom Build Tool options, this answer and your hint did the trick – int ermedi_8 Nov 07 '18 at 09:55
  • Yes, this is the issue. I had this same problem, and the issue in my case was that I'd created the *.h file, but hadn't added it to my VS project. It compiled just fine (because #include), but wouldn't link because the MOC compiler was never running. – T.E.D. Jun 27 '19 at 22:04
  • 2
    On VS 2019 it is called `"Qt Meta-Object Compiler (moc)"`, worked for me when I changed it. – danieltakeshi Oct 06 '19 at 16:00
9

I added cpp/ui files to my project manually, but forgot to add the header file explicitly as header file. Now when compiling I got a similar error message as above and the moc_*.cpp file(s) were not generated in the debug (or release) directory of the build. That was not such an obvious mistake, qmake did not complain and other than the linker message I got no errors.

So if anyone encounters the same problem again (or makes the same copy & pase mistake): make sure the header files have also been added to your project file

Vinoj John Hosan
  • 6,448
  • 2
  • 41
  • 37
8

If your moc files are generated in the visual studio project try to include them into project if they are not included into project then rebuild.

Akın Yılmaz
  • 300
  • 5
  • 18
6

I had the same problem in Visual Studio, and solved it by taking the following steps:

  1. Right-click header file in solution Explorer
  2. Properties
  3. Change "Item Type" to "Custom Build Tool"

Then in the Custom Build Tool configuration:

  1. Go to General
  2. set "Command Line" to:

    "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fStdAfx.h" "-f../../../src/FileName.h" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DWIN32_LEAN_AND_MEAN -DDIS_VERSION=7 -D_MATH_DEFINES_DEFINED "-I.\SFML_STATIC" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork"

  3. set "Outputs" to:

    .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp

  4. set "Additional Dependencies" to:
    $(QTDIR)\bin\moc.exe;%(FullPath)


Your exact values may be different. They are usually applied via a Qt plugin.

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • Worked for me, except that I could stop after the first set of 1,2,3 steps; the Custom Build Tool configuration is presumably already defined somewhere. I'm using Visual Studio 2017. – Captain Normal Oct 19 '18 at 11:41
5

I had this problem with Visual Studio 2012 when I had a Q_OBJECT class definition in my cpp file. Moving the class definition to the header file resolved the issue.

It looks like it should be possible to support Q_OBJECT class in cpp file by adding the cpp file to moc but I did not try this.

Edward
  • 148
  • 2
  • 7
  • 1
    This was my problem as well. Annoying to have to expose an internal class in the header file though. – Zitrax Jun 02 '17 at 08:46
4

I use CMake to manage Qt projects and the new Q_OBJECT needs to be added under the QT4_WRAP_CPP call. This will generate the moc_*.cxx for inclusion in the project and clean up the unresolved externals.

whatnick
  • 5,400
  • 3
  • 19
  • 35
3

My problem was that one of my files that used a Qt macro didn't get moc'ed. I found out, that the Qt Plugin for Visual Studio doesn't recognize the Q_NAMESPACE macro and therefore doesn't add the file to the moc'ing list.

So I used the solution from this answer to add the file to the mic'ing list:

You should find a .h file which has successfully generated "moc_*", and copy all the contents in "Custom Build Tool -> General" to the new .h file setting page.

Be careful with the different options for Debug and Release-Mode.

After that, build your project.

Build it once each in Debug and Release-Mode

Finally, add the generated "moc_*" file to your project.

Now, "moc_filename.cpp" should be in Generated Files\Debug and Generated Files\Release.

Right click on each of them and change thair properties:

  • The file in Debug: Change configuration to Release and then change General->Excluded from build to yes.
  • The file in Release: Change configuration to Debug and then change General->Excluded from build to yes.
Darkproduct
  • 1,062
  • 13
  • 28
2

Faced this issue in case of chained CMake targets. Turned out I had to enable CMAKE_AUTOMOC even in targets that didn't use Qt directly (transitively). Also turned out that CMAKE_AUTOMOC can't be used w/o find_package(QtX) in same CMakeLists.txt or CMakeLists.txt of parent.

Pugsley
  • 1,146
  • 14
  • 14
1

In my case (using QtAdd-in with VS2012 and Qt v4.8.4) none of the above suggestions worked. For some reason VS could not generate proper moc files (build output: No relevant classes found. No output generated.) and when I compiled relevant headers by hand (setting qt moc as a compiler and clicking 'Compile') it produced empty moc file.

What did work was to compile all necessary mocs from command line (moc -o moc_SomeClass.cpp SomeClass.h) and then replace the wrong ones in GeneratedFiles folder.

This is only workaround (and not a convenient one for a big project) to have your project build succesfully, but does not really explain strange VS/QtAdd-in behaviour.

dianull
  • 43
  • 1
  • 5
1

Using QtAdd-in with VS2010 i realized the moc_*.cpp files were updated in the GeneratedFiles/Debug folder although i was in release mode. Copying the files into the Release folder worked for me.

zengaja
  • 11
  • 1
1

I've encountered this problem with the use of a "private class" in Qt when employing the "PIMPL" (private implementation) programming pattern. Qt uses this model all through out their source code. I have come to really like it myself.

This technique involves the use of a "private" forward-declared class in a public header file, which will be be used by the "public" class (i.e. it's "parent"). The parent then has a pointer to an instance of the private class as a data member.

The "private" class is defined entirely within the cpp file for the public one. There is NO header file for the private class.

All of the "dirty work" is done with that private class. This hides all of the implementation of your public class including every other private member typically (both data and functions).

I highly recommend learning about the PIMPL pattern - especially if you are going ever read the internal Qt source.

Without explaining that coding style further, here's the point as it relates to this question... To get the Q_OBJECT macro to work inside the cpp for the "private" class to be QObject which can use signals/slot etc., you needed to explicitly include the .moc to the public class inside the cpp:

#include "MyPublicClass.moc"

You can ignore any IDE warnings about this line.

I'm not sure if it matters exactly off hand, but that inclusion I always see done AFTER the private class definition, rather than at the top of the cpp (like includes are typically placed). So, the cpp layout goes like this:

  1. "Normal" includes are defined.
  2. The private class is defined.
  3. The moc for the public class is #included.
  4. The public class implementation is defined.
BuvinJ
  • 10,221
  • 5
  • 83
  • 96
1

I know that this is a very old question, but it seems to be still interesting (I've been here at least 4 or 5 times in the last months) and seems like I found another reason for which is possible to get this error.

In my case in the header file I wrongly typed:

#include "MyClass.h""

Only after inspecting the whole output I found out that at that line the compiler was emitting a warning.

Now that I removed the additional quotation mark my QObject compiles perfectly!

Brutus
  • 790
  • 3
  • 10
  • 27
1

Visual Studio 2017.

I've added file to already set up Qt project and got this error. How I fixed it:

Right click on the header in Solution Explorer Properties... -> Configuration Properties -> General -> Item Type Change from C/C++ Header to Qt Meta-Object Compiler (moc)

voila :)

ashrasmun
  • 490
  • 6
  • 11
1

For Visual Studio 2022 (with Qt VS Tools extention)

In Solution Explorer right click on the affected header file and select Properties.
Under "Configurations Properties -> General -> Item Type" select the option "Qt Meta-Object Compiler (moc)". Then rebuild the project.

Code Gorilla
  • 962
  • 9
  • 23
0

This happened to me recently when switching from MingW to MSVC. I had a prototyped class/struct listed as a class, and MingW didn't mind.

MSVC definitely sees a difference between class and struct when prototyping is concerned.

Hope that helps someone else one day.

phyatt
  • 18,472
  • 5
  • 61
  • 80
0

In my case, none of the above worked but it was totally my mistake.

I had overrided virtual functions in .h file (declared them) but had never defined them in .cpp :)

zar
  • 11,361
  • 14
  • 96
  • 178
0

Either answer works for me in the VS 2013 environment. I eventually solve the problem by removing the .h/.cpp from project, and adding it back.

Adam Woo
  • 31
  • 4
0

I am working in VS2015 with an integrated Perforce p4v client. In my case Perforce tried to add moc file to a depo, when I reverted this operation, Perforce removed this moc file from project and deleted it. The file was recreated after the next compilation, but it wasn't included in project, I have to add it manually to Generated files, when I finally understood what was the problem.

Flot2011
  • 4,601
  • 3
  • 44
  • 61
0

I have the same problem, my solution was the encoding( my file with "UTF16LE BOM" can't generate with moc.exe ) , y create another file with ASCII enconding and it work.

HxD HexEditor can help you to see the codification.

Jefferson Rondan
  • 103
  • 1
  • 10
0

For me, this is the cause: some header or source file not included in QT's project file

Sanbrother
  • 601
  • 5
  • 12
0

In my case I had the .h and the .cpp file for the problematic QObject ancestor in subfolders of the project. When I moved them next to the CMakeLists.txt (project root folder) it linked successfully. I'm probably missing some CMake command to include mocs fot files in subdirectories.

burnack
  • 9
  • 1
0

when I removed Q_OBJECT it works fine.

I'm using Clion + CMake + MSVC/14.31.31103.

Is it because Q_OBJECT no longer needed after these?

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
isudfv
  • 179
  • 1
  • 9
0

In Qt Creator

It turned out I had this error because I added Q_OBJECT afterwards in the .h file.

I managed to fix it after removing and adding the file back into the project.

Happy coding...

Carl Bosch
  • 1,281
  • 16
  • 14
-1

I solved my problem by adding this to my header file :

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H

... // all the header file content.

#endif
Nadjib Dz
  • 71
  • 6