Qt, VS2005, Qwt - Can't use Q_OBJECT in class derived from Qwt widgets
Asked Answered
V

5

4

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.

Void answered 7/1, 2010 at 17:17 Comment(0)
I
10

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

Illdisposed answered 19/1, 2010 at 6:15 Comment(1)
+1: Thanks, it helped! I think, a define switch is missing in QWT. Something like "if using in this library, set QWT_DLL to Q_DECL_EXPORT, else set QWT_DLL to empty". That's why you should set QWT_DLL to empty manually if using QWT headers.Torbert
D
1

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 !

Demerol answered 8/1, 2010 at 6:9 Comment(6)
I would suggest you something, it's probably not realisable, but will be maybe helpful for futures projects. I'm using a script package that a friend of mine developped. You can find it here : dprog.net/joomla/… There is a little job to do to set it up, like specifying which VS you're using, which Qt version, where is your .PRO file, etc... And then everything else is done automatically, adding new added files, creating .PRI files, vcproj files... It's really good...Demerol
With that package, for example, when i add a file, i put it in the correct folder, beside my .PRO file. I launch one of the script called "generate_vcproj.bat" and the scripts generate everything... Then I use "Launch_ide.bat" and my VS launches itself with all set up (moc files as well ;) )Demerol
As for this answer, nope... there's definitely a MOC file for this. (moc_GaugeWidget1.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtDial::staticMetaObject" (?staticMetaObject@QwtDial@@2UQMetaObject@@B)) ... so, there's some other issue/bug going on.Void
the moc_GaugeWidget1.obj is based on moc_GaugeWidget.cpp, which is the MOC file for the class I added the Q_OBJECT to.Void
Hey, I've found this, maybe it could solve your problem : "The problem seemed to be the moc files which are generated by QT. There are two versions, one for debug and one for release. Switching between configurations should toggle the right files, which means one of both is always excluded from the build. If the files get mixed up, for example some moc file meant for release is included when building for debug, the file is compiled but can not be linked, since it is the wrong configuration......."Demerol
"............ You can easily check this by looking at your Generated files. Right click the files, look at the Properties and see if all files in the debug folder are excluded from the build when in release configuration and vice versa."Demerol
S
1

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!

Sortie answered 21/4, 2010 at 11:37 Comment(0)
S
1

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!

Spectrophotometer answered 5/7, 2010 at 9:44 Comment(0)
A
0

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.

Avery answered 17/4, 2011 at 4:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.