对 vtable 的未定义引用...Q_OBJECT 宏
当我取消注释信号槽所需的 Q_OBJECT 宏时,我得到了对 MyApp 错误的 vtable 的未定义引用,但是如果没有该宏,它可以完美编译,但如果没有它,我就无法使用信号和槽。我想我可能做错了一些愚蠢的错误,但请尝试帮助,因为我真的找不到问题。 O,我知道我的代码不整洁,正在处理它。
myapp.h:
#ifndef MYAPP_H
#define MYAPP_H
#include <QApplication>
#include <QEvent>
#include <QObject>
#include <QDebug>
class MyApp : public QApplication
{
public:
MyApp( int argc, char** argv );
protected:
bool eventFilter(QObject *object, QEvent *event);
signals:
void focusG();
void focusL();
};
#endif // MYAPP_H
myapp.cpp:
#include "myapp.h"
MyApp::MyApp(int argc, char **argv): QApplication(argc, argv)
{
installEventFilter(this);
}
bool MyApp::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::ApplicationDeactivate)
{
qDebug() << "Focus lost";
//focusL();
}
if (event->type() == QEvent::ApplicationActivate)
{
qDebug() << "Focus gained";
//focusG();
}
return false;
}
main.cpp:
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include <QObject>
#include <QGraphicsObject>
#include <QTimer>
#include <QVariant>
#include "timecontrol.h"
#include "scorecontrol.h"
#include "Retry.h"
#include <QEvent>
#include "myapp.h"
int main(int argc, char *argv[])
{
//QApplication app(argc, argv);
MyApp app(argc, argv);
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockLandscape);
viewer.setMainQmlFile(QLatin1String("qml/Raker/main.qml"));
viewer.showExpanded();
QObject *rootObject = viewer.rootObject();
QTimer *timmer = new QTimer;
timmer->setInterval(1000);
TimeControl *timcon = new TimeControl;
scorecontrol *scorer = new scorecontrol;
Retry *probeer = new Retry;
QObject::connect(timmer, SIGNAL(timeout()), timcon, SLOT(updateTime()));
QObject::connect(timcon, SIGNAL(setTime(QVariant)), rootObject, SLOT(setTime(QVariant)));
QObject::connect(rootObject, SIGNAL(blockClicked(int, int)), scorer, SLOT(checkRight(int, int)));
QObject::connect(scorer, SIGNAL(setScore(QVariant)), rootObject, SLOT(setScore(QVariant)));
QObject::connect(scorer, SIGNAL(setState(QVariant)), rootObject, SLOT(setState(QVariant)));
QObject::connect(rootObject, SIGNAL(start()), probeer, SLOT(Reetry()));
QObject::connect(probeer, SIGNAL(start()), timmer, SLOT(start()));
QObject::connect(probeer, SIGNAL(stop()), timmer, SLOT(stop()));
QObject::connect(probeer, SIGNAL(start(int)), scorer, SLOT(randomNum(int)));
QObject::connect(probeer, SIGNAL(sReset()), timcon, SLOT(reset()));
QObject::connect(probeer, SIGNAL(tReset()), scorer, SLOT(reset()));
QObject::connect(timcon, SIGNAL(timeOut()), scorer, SLOT(reset()));
QObject::connect(timcon, SIGNAL(setState(QVariant)), rootObject, SLOT(setState(QVariant)));
QObject::connect(timcon, SIGNAL(changeFinal()), scorer, SLOT(changeFinal()));
QObject::connect(scorer, SIGNAL(setFinal(QVariant)), rootObject, SLOT(setFinal(QVariant)));
QObject::connect(&app, SIGNAL(focusL()), probeer, SLOT(focusL()));
QObject::connect(&app, SIGNAL(focusG()), probeer, SLOT(focusG()));
return app.exec();
}
BlockToucher.pro:
# Add more folders to ship with the application, here
folder_01.source = qml/Raker
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01
# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =
symbian:TARGET.UID3 = 0x2004b49f
# Smart Installer package's UID
# This UID is from the protected range and therefore the package will
# fail to install if self-signed. By default qmake uses the unprotected
# range value if unprotected UID is defined for the application and
# 0x2002CCCF value if protected UID is given to the application
symbian:DEPLOYMENT.installer_header = 0x2002CCCF
# Allow network access on Symbian
symbian {
#TARGET.CAPABILITY += NetworkServices
vendorinfo = "%{\"Gerhard de Clercq\"}" ":\"Gerhard de Clercq\""
ICON = BlockToucher.svg
}
# If your application uses the Qt Mobility libraries, uncomment the following
# lines and add the respective components to the MOBILITY variable.
# CONFIG += mobility
# MOBILITY +=
# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp \
timecontrol.cpp \
scorecontrol.cpp \
Retry.cpp \
myapp.cpp \
myapplication.cpp
# Please do not modify the following two lines. Required for deployment.
include(qmlapplicationviewer/qmlapplicationviewer.pri)
qtcAddDeployment()
HEADERS += \
timecontrol.h \
scorecontrol.h \
Retry.h \
myapp.h \
myapplication.h
OTHER_FILES += \
qtc_packaging/debian_fremantle/rules \
qtc_packaging/debian_fremantle/README \
qtc_packaging/debian_fremantle/copyright \
qtc_packaging/debian_fremantle/control \
qtc_packaging/debian_fremantle/compat \
qtc_packaging/debian_fremantle/changelog
compat \
qtc_packaging/debian_fremantle/changelog
When I uncomment the Q_OBJECT macro that I need for signal-slot I get a undefined reference to vtable for MyApp error, but without the macro it compiles perfectly but I can't use signals and slots without it. I think I may be doing something stupid wrong, but please try helping because I realy can't find the problem. O and I know my code is untidy and am working on it.
myapp.h:
#ifndef MYAPP_H
#define MYAPP_H
#include <QApplication>
#include <QEvent>
#include <QObject>
#include <QDebug>
class MyApp : public QApplication
{
public:
MyApp( int argc, char** argv );
protected:
bool eventFilter(QObject *object, QEvent *event);
signals:
void focusG();
void focusL();
};
#endif // MYAPP_H
myapp.cpp:
#include "myapp.h"
MyApp::MyApp(int argc, char **argv): QApplication(argc, argv)
{
installEventFilter(this);
}
bool MyApp::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::ApplicationDeactivate)
{
qDebug() << "Focus lost";
//focusL();
}
if (event->type() == QEvent::ApplicationActivate)
{
qDebug() << "Focus gained";
//focusG();
}
return false;
}
main.cpp:
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include <QObject>
#include <QGraphicsObject>
#include <QTimer>
#include <QVariant>
#include "timecontrol.h"
#include "scorecontrol.h"
#include "Retry.h"
#include <QEvent>
#include "myapp.h"
int main(int argc, char *argv[])
{
//QApplication app(argc, argv);
MyApp app(argc, argv);
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockLandscape);
viewer.setMainQmlFile(QLatin1String("qml/Raker/main.qml"));
viewer.showExpanded();
QObject *rootObject = viewer.rootObject();
QTimer *timmer = new QTimer;
timmer->setInterval(1000);
TimeControl *timcon = new TimeControl;
scorecontrol *scorer = new scorecontrol;
Retry *probeer = new Retry;
QObject::connect(timmer, SIGNAL(timeout()), timcon, SLOT(updateTime()));
QObject::connect(timcon, SIGNAL(setTime(QVariant)), rootObject, SLOT(setTime(QVariant)));
QObject::connect(rootObject, SIGNAL(blockClicked(int, int)), scorer, SLOT(checkRight(int, int)));
QObject::connect(scorer, SIGNAL(setScore(QVariant)), rootObject, SLOT(setScore(QVariant)));
QObject::connect(scorer, SIGNAL(setState(QVariant)), rootObject, SLOT(setState(QVariant)));
QObject::connect(rootObject, SIGNAL(start()), probeer, SLOT(Reetry()));
QObject::connect(probeer, SIGNAL(start()), timmer, SLOT(start()));
QObject::connect(probeer, SIGNAL(stop()), timmer, SLOT(stop()));
QObject::connect(probeer, SIGNAL(start(int)), scorer, SLOT(randomNum(int)));
QObject::connect(probeer, SIGNAL(sReset()), timcon, SLOT(reset()));
QObject::connect(probeer, SIGNAL(tReset()), scorer, SLOT(reset()));
QObject::connect(timcon, SIGNAL(timeOut()), scorer, SLOT(reset()));
QObject::connect(timcon, SIGNAL(setState(QVariant)), rootObject, SLOT(setState(QVariant)));
QObject::connect(timcon, SIGNAL(changeFinal()), scorer, SLOT(changeFinal()));
QObject::connect(scorer, SIGNAL(setFinal(QVariant)), rootObject, SLOT(setFinal(QVariant)));
QObject::connect(&app, SIGNAL(focusL()), probeer, SLOT(focusL()));
QObject::connect(&app, SIGNAL(focusG()), probeer, SLOT(focusG()));
return app.exec();
}
BlockToucher.pro:
# Add more folders to ship with the application, here
folder_01.source = qml/Raker
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01
# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =
symbian:TARGET.UID3 = 0x2004b49f
# Smart Installer package's UID
# This UID is from the protected range and therefore the package will
# fail to install if self-signed. By default qmake uses the unprotected
# range value if unprotected UID is defined for the application and
# 0x2002CCCF value if protected UID is given to the application
symbian:DEPLOYMENT.installer_header = 0x2002CCCF
# Allow network access on Symbian
symbian {
#TARGET.CAPABILITY += NetworkServices
vendorinfo = "%{\"Gerhard de Clercq\"}" ":\"Gerhard de Clercq\""
ICON = BlockToucher.svg
}
# If your application uses the Qt Mobility libraries, uncomment the following
# lines and add the respective components to the MOBILITY variable.
# CONFIG += mobility
# MOBILITY +=
# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp \
timecontrol.cpp \
scorecontrol.cpp \
Retry.cpp \
myapp.cpp \
myapplication.cpp
# Please do not modify the following two lines. Required for deployment.
include(qmlapplicationviewer/qmlapplicationviewer.pri)
qtcAddDeployment()
HEADERS += \
timecontrol.h \
scorecontrol.h \
Retry.h \
myapp.h \
myapplication.h
OTHER_FILES += \
qtc_packaging/debian_fremantle/rules \
qtc_packaging/debian_fremantle/README \
qtc_packaging/debian_fremantle/copyright \
qtc_packaging/debian_fremantle/control \
qtc_packaging/debian_fremantle/compat \
qtc_packaging/debian_fremantle/changelog
compat \
qtc_packaging/debian_fremantle/changelog
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
MOC 系统使用 Q_OBJECT 来生成信号所需的代码。我最好的猜测是您的项目中没有包含 MOC 生成的文件(它生成的 CPP 文件)。
如何执行此操作很大程度上取决于您的构建系统(CMake、QMake、AUtomake、MSVC),但您应该首先参考 QMake 教程。
也就是说,当我忘记更新 Cmake 文件并拥有 Q_OBJECT 时,有时会出现对 vtable 的未定义引用的错误。
另外,您的 MyApp 构造函数是错误的,签名必须是:
如果您使用命令行参数,则
&
很重要。Q_OBJECT is used by the MOC system to produce the code you need for the signals. My best guess would be that you are not included the MOC generated files in your project (the CPP files which it generates).
How you do this greatly depends on your build system (CMake, QMake, AUtomake, MSVC) but you should refer to the tutorial with QMake first.
That is, the undefined reference to vtable is the error I sometimes get when I forget to update my Cmake files and have a Q_OBJECT.
Also, your ctor for MyApp is wrong, the signature must be:
The
&
is important should you ever use command-line parameters.当我决定将
Q_OBJECT
添加到我的头文件中时,我遇到了同样的问题。首先尝试手动运行
qmake
。如果没有解决,请删除构建文件夹并重新构建项目
如果构建所有项目是一项繁重的任务,请尝试以下步骤:
祝你好运:)
I had same issue when i decided to add
Q_OBJECT
into my header file.First try run
qmake
manually.If not resolved, so delete build folder and build project again
If building all of the project is a heavy task, so try following steps:
Good luck :)