Q_OBJECT抛出'未定义的引用vtable'错误
我在Windows 7 Ultimate 32位上使用Qt Creator 2.0.1和Qt 4.7.0(32位)。
考虑下面的代码,这是产生错误的最小值:
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; }
上面的代码片段导致以下链接器错误:
在函数“T”中:
未定义的引用'vtable for T'
未定义的引用'vtable for T'
在函数'〜T'中:
未定义的引用'vtable for T'
未定义的引用'vtable for T'
如果我注释掉包含Q_OBJECT
的行,它编译得很好。 我需要与QGraphicsItem
信号和插槽,所以我需要Q_OBJECT
。
代码有什么问题? 谢谢。
这是因为MOC生成的单位不包含在链接过程中。 或者,也许它不是生成的。 我要做的第一件事是将类声明放在一个单独的头文件中,也许构build系统不扫描实现文件。
另一种可能性是这个类别曾经不属于Qt元对象系统(也就是说,它没有Q_OBJECT或可能根本不从QObjectinheritance),所以需要再次运行qmake来创buildMOC的必要规则。 强制qmake运行的最简单方法是对项目文件进行一些微不足道的更改以更新其时间戳,例如添加并删除一些空白区域。 或者,如果您使用的是Qt Creator,那么只需从项目上下文菜单中select“运行qmake”即可。
如果你想在一个源文件中定义一个QObject
子类,那么你需要添加该行
#include "file.moc"
在类定义之后的某个时刻,源文件的名称是file.cpp。 你当然需要重新运行qmake
,以便运行moc
的相应规则被添加到Makefile中。
只有在头文件中,类定义中Q_OBJECT
的存在才会调用moc
。 如果它是一个源文件,你需要这个额外的行来强制moc
被使用。
我相信以前也有类似的问题,但是我找不到。
把你的Q_OBJECT类放在不同的文件中。 每个class级都有一个.h和一个.cpp。 Qt的元对象macros在这方面很挑剔。
此外,您可以使用QGraphicsObject为您的目的。 在那里节省一些时间。
编辑:我看到你正在使用造物主。 在New File或Project中使用New C ++ Class函数以“正确的方式”创build文件:)
这里是工作代码添加了其他问题中提供的所有修补程序(尝试干净的编译和这些修复帮助):
#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.
所以实际信用Troubadour和serge_gubenko
有几件事要看:
- 在你的pro文件中添加QT + = gui
- 确保你只在你的头文件中定义你的QObject派生类(编辑:如Troubadour指出的,这不是必需的)
- 将Q_INTERFACES(QGraphicsItem)添加到您的T类的声明中
下面是一个例子:
日:
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); }
我试过编译上面的代码,没有问题。
希望这有助于问候