2011-12-17 9 views
8

Sono relativamente nuovo a Qt. Ho apportato alcune semplici modifiche a un'applicazione Qt esistente, ma non ho ancora creato nulla da zero.
Inoltre, non ho molta esperienza con alcuni aspetti del C++ in generale (ereditarietà delle classi ecc.).QTimer :: singleShot() cerca lo slot specificato nella classe padre dell'oggetto specificato, non l'oggetto stesso

Ho creato un nuovo progetto Code :: Blocks basato su Qt4 e modificato un po 'il modello. Ho aggiunto due file.
In questo momento il progetto contiene tre file: main.cpp, app.h e app.cpp.
Questo è il contenuto della main.cpp:

#include <QTimer> 

#include "app.h" 

int main(int argc, char* argv[]) { 
    TestApp app(argc, argv); 

    QTimer::singleShot(1000, &app, SLOT(timeout())); 

    return app.exec(); 
} 

Questo è ciò che app.h assomiglia:

#ifndef APP_H_INCLUDED 
#define APP_H_INCLUDED 

#include <QApplication> 

class TestApp: public QApplication { 
    public: 
    TestApp(int &argc, char **argv); 
    public slots: 
    void timeout(); 
}; 

#endif 

E questo è app.cpp:

#include "app.h" 

#include <QDebug> 

TestApp::TestApp(int &argc, char **argv): QApplication(argc, argv) { 
} 

void TestApp::timeout() { 
    qDebug() << "timeout called"; 
} 

Mi aspettavo il progr sto per stampare "timeout chiamato" un secondo dopo l'avvio. Sfortunatamente, questo non funziona. Quando QTimer::singleShot() si chiama, la console dice:

Object::connect: No such slot QApplication::timeout() in [path to the main.cpp file] 
Object::connect: (receiver name: 'QtTests') 

non ho idea di come affrontare questo. Grazie in anticipo.

risposta

6

Stai semplicemente manca la macro Q_OBJECT nella classe TestApp:

class TestApp: public QApplication { 
    Q_OBJECT 

    public: 
    ... 

Ciò è necessario per l'intera infrastruttura di segnale/slot di lavorare (e derivante da una classe che ha questa macro non è sufficiente) .

(Assicuratevi di fare un pieno, generazione pulita dopo che il cambiamento -. E se non si utilizza qmake o qualche altro sistema di compilazione Qt-aware, è necessario eseguire moc te stesso)

Per riferimento, vedere i documenti: QObject

noti che la macro Q_OBJECT è obbligatoria per qualsiasi oggetto che implementa segnali, fessure o proprietà. È inoltre necessario eseguire il Meta Object Compiler sul file di origine. Raccomandiamo vivamente l'uso di questa macro in tutte le sottoclassi di QObject indipendentemente dal fatto che utilizzino effettivamente segnali, slot e proprietà, poiché l'impossibilità di farlo può portare alcune funzioni a mostrare comportamenti strani.

3

È necessario creare un file moc, che viene creato con qmake se si inserisce la macro Q_OBJECT nella classe.

Così, per risolvere il tuo esempio, è necessario la classe cambiato in questo:

class TestApp: public QApplication { 
    Q_OBJECT 
    public: 
    TestApp(int &argc, char **argv); 
    public slots: 
    void timeout(); 
}; 
+0

+1 per menzionare il * moc file *! Inserire 'Q_OBJECT' nella dichiarazione della classe è insufficiente quando Qmake non viene chiamato, ad esempio quando si costruisce con CMake. – Melebius

+1

@Melebius Per questo, è necessario utilizzare 'QT4_WRAP_CPP', quindi cmake analizzerà le intestazioni e genererà i file moc. –