2011-10-26 12 views
0

信号スロットに必要なQ_OBJECTマクロのコメントを外すと、MyAppエラーのvtableへの未定義の参照が得られますが、マクロがなければ完全にコンパイルされますが、信号は使用できませんそれなしのスロット。私は何か愚かな間違ったことをしているかもしれないと思うが、私は本当に問題を見つけることができないので、手伝ってください。私のコードはうまくいきませんし、それに取り組んでいます。未定義のvtableへの参照... Q_OBJECTマクロ

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 

答えて

4

Q_OBJECTは、信号に必要なコードを生成するためにMOCシステムで使用されます。私の推測では、プロジェクトにMOCで生成されたファイル(生成するCPPファイル)は含まれていないと考えられます。

これを行う方法は、ビルドシステム(CMake、QMake、AUtomake、MSVC)に大きく依存しますが、まずQMakeのチュートリアルを参照する必要があります。

つまり、vtableへの未定義の参照は、私がCmakeファイルを更新するのを忘れてQ_OBJECTを持つことを忘れると時々起こるエラーです。 MyAppのためのあなたのctorが間違っている

また、署名がなければなりません:あなたは、コマンドラインパラメータを使用する必要があります

MyApp(int & argc, char** argv); 

&が重要です。

+0

私はその前にqmakeのを実行するように見えるのQt Creatorを使用します – Gerharddc

+1

@Gerhman .proファイルが変更された場合にのみ実行されます。 non-mocableファイルがmocable(= 'Q_OBJECT'マクロを含む)になると、qmakeは手動で実行しなければならないので、Makefileはmocを実行するように更新されます。 – alexisdm

+0

ありがとうございました! – Gerharddc

1

Q_OBJECTを私のヘッダーファイルに追加することにしたとき、同じ問題が発生しました。
スーパー簡単な解決策はこれです:

  1. その基底クラスとして
  2. をQObjectを使用して新しい一時クラスの追加]をダブル
  3. 新しい一時クラスを使用して、任意の間違いのためのあなたのヘッダーとソースファイルをチェックし、プロジェクトをビルドします。これは、(.Hと.cppファイルと相対.PROファイル上の行)

をお楽しみに成功

  • は完全にあなたの一時クラスを削除建てなければならない:)

  • 関連する問題