2011-10-26 3 views
3

J'ai une classe simple qui arrête et démarre une minuterie quand mon programme gagne et perd le focus mais il donne l'erreur que QObject est une base ambiguë de MyApp sur chaque connexion signal-slot. Voici le code correspondant:QObject inheritance Ambiguous Base

class MyApp : public QApplication, public QObject 
{ 
    Q_OBJECT 
    ... 
} 

Voici mon (désordre) 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[]) 
    { 
     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(); 
    } 

MyApp.cpp:

#include "myapp.h" 
    #include <QDebug> 
    #include <QObject> 

    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; 
    } 

Répondre

9

Avec votre exemple actuel, vous avez créé un système d'héritage partagé, où votre objet se retrouve avec deux instances d'une QObject ... il y a une base QObject pour le QApplication, et une autre pour la classe MyApp réelle. Cela créera une ambiguïté, car l'accès à une méthode QObject héritée ou à un membre de données ne saura pas exactement quel objet de base hérité accéder.

En ce moment, votre diagramme d'héritage ressemble à ceci (notez les deux instances de QObject votre objet MyApp hérite):

| QObject |   | QObject | 
     \    /
     \   | QApplication | 
     \   /
      \   /
     | MyApp | 

Vous devez garder votre diagramme d'héritage linéaire, plutôt que d'avoir un système d'héritage partagé, et cela signifie avoir une classe dérivée qui contient seulement une instance de la classe de base. Donc, vous voulez quelque chose comme ceci:

QObject 
     | 
     | 
    QApplication 
     | 
     | 
    MyApp 
+0

Ok, mais maintenant obtenir une référence indéfinie à 'vtable pour MyApp' sur le "{" au-dessus de la macro Q_OBJECT, et dans MyApp.cpp sur les deux occurrences de MyApp sur cette ligne : "MyApp :: MyApp (int argc, char ** argv): QApplication (argc, argv)" – Gerharddc

+1

A quoi ressemble votre main() '? ... Je voudrais également appuyer le commentaire de Laurent sur l'exécution de 'qmake' aussi bien sur votre projet en premier. – Jason

+0

J'ai ajouté ma main à ma qeustion – Gerharddc

4

QApplication est déjà un QObject, vous devrait simplement écrire:

class MyApp : public QApplication 
{ 
    Q_OBJECT 
... 

} 
+0

Ok, mais maintenant obtenir une référence non définie à « vtable pour MyApp » sur les « { » au-dessus de la macro Q_OBJECT, et MyApp.cpp sur les deux occurences de MyApp sur cette ligne : "MyApp :: MyApp (int argc, char ** argv): QApplication (argc, argv)" – Gerharddc

+2

Avez-vous exécuté qmake sur votre projet en premier? –

+0

J'utilise Qt Creator et il semble le faire automatiquement – Gerharddc