Qt, VS2005, Qwt - Can't use Q_OBJECT in class

2019-02-14 05:30发布

问题:

We've compiled QT 4.6 and QWT 5.2.0 for VS2005.

We're trying to derive a class from QwtDial, and the derived class has slots. So, we need to add the Q_OBJECT macro. However, when we do that, the linker chokes out this error:

error LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtDial::staticMetaObject" (?staticMetaObject@QwtDial@@2UQMetaObject@@B)

I've looked at the Qwt.dll with depends, and it has that function. Looking at the .lib file with a hex editor shows it has an exact match for that name-mangled string.

We have the Qwt lib in the path. Actually, if I rename the lib, then it gives an error that it can't find the lib file. So, we know it's looking at the right lib.

If we skip the Q_OBJECT, then everything links and draws correctly using several QWT widgets, including our non-Q_OBJECT Qwt derived classes.

Does anyone know what can cause this really annoying linker issue?

UPDATE:

I've verified that the class I add the Q_OBJECT to definitely is getting a MOC file generated for it. The linker error is actually coming from this generated MOC file:

moc_GaugeWidget1.obj : error LNK2001: unresolved external symbol "public: static
    struct QMetaObject const QwtDial::staticMetaObject" 
    (?staticMetaObject@QwtDial@@2UQMetaObject@@B)

So, it's looking like something quite stange and atypical. The symbol is definitely in the lib.

回答1:

I am having the same problem. Well, I'm updating an old project using Qt4.4 and VC2003, and I'm using QwtPlot instead of QwtDial. The error is:

LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtPlot::staticMetaObject" (?staticMetaObject@QwtPlot@@2UQMetaObject@@B)

Just that. Nothing else. I've found forum references pointing to issues with debug/release mixups and possibly something to do with removing the Qt Designer plugin.

This seems to be working for me: Add the line: "DEFINES += QWT_DLL" to the top of the project.pro file.

qmake project.pro

nmake release



回答2:

I'm not sure about this answer, but here are some informations :

It seems to me that your derived class doesn't have a matching moc_ file ! The moc files are typically used when using the Q_OBJECT macro... Your project's moc informations are stored in the Makefile, Makefile.debug and Makefile.release files ! It is this file that tells which .cpp files need a moc file and which don't.

You can find documentation on the moc in QtAssistant : http://qt.nokia.com/doc/4.6/moc.html

Now, to check this, you need to go in your "generated" folder and look for a file named "moc_yourDerivedClass.cpp".

If you can't find any matching file, you need to go through the qmake process again with yourderivedClass... Maybe when you first used qmake, the Q_OBJECT macro wasn't in the class yet and therefore, no moc file has been created...

I hope it helps you a bit !



回答3:

The problem is with moc file.You should use Q_DECL_EXPORT (or some thing else like it) in QwtPlot definition which tell compiler this class is usable by other library but the parts of class generated in moc file dosn't contains these so when you linking these library with other program it dosn't know how to link those parts. Anyway I don't have any idea how to tell these to Qt!



回答4:

Exactly the same issue here with qwt 5.2.1, qt 4.6 and VS2008. the same code compiles perfectly in Linux. All moc files are properly generated and processed, no release/debug mixed libraries are there, I am going to report it to qwt bugs when I have time.

adding QWT_DLL to the list of defines (project properties->c++->preprocessor->definitions) indeed solves the problem!



回答5:

Try running qmake again in the project directory.

$ qmake -project

$ qmake -tp vc

This is what fixed the problem for me. Reading the explanations of "it looks like you have a moc file problem", that many people have given, left me unclear on what to do.

I think I caused my own problems on this one though. I right clicked and compiled the .ui file in my project before building the whole project. Somehow that didn't fully generate all the files needed. Anyway, running qmake is a useful thing to do if you suddenly run into problems that weren't previously there.

However, there was another thing I noticed about in my project settings, none of the preprocessor directives were set. Running qmake again fixed this.