2011-05-02 22 views
19

ejemplo Después de este enlace: http://developer.kde.org/documentation/books/kde-2.0-development/ch03lev1sec3.htmlQt: Señales y ranuras de error: undefined reference to `vtable para

#include <QObject> 
#include <QPushButton> 
#include <iostream> 
using namespace std; 

class MyWindow : public QWidget 
{ 
    Q_OBJECT // Enable slots and signals 
    public: 
     MyWindow(); 
    private slots: 
     void slotButton1(); 
     void slotButton2(); 
     void slotButtons(); 
    private: 
     QPushButton *button1; 
     QPushButton *button2; 
}; 

MyWindow :: MyWindow() : QWidget() 
{ 
    // Create button1 and connect button1->clicked() to this->slotButton1() 
    button1 = new QPushButton("Button1", this); 
    button1->setGeometry(10,10,100,40); 
    button1->show(); 
    connect(button1, SIGNAL(clicked()), this, SLOT(slotButton1())); 

    // Create button2 and connect button2->clicked() to this->slotButton2() 
    button2 = new QPushButton("Button2", this); 
    button2->setGeometry(110,10,100,40); 
    button2->show(); 
    connect(button2, SIGNAL(clicked()), this, SLOT(slotButton2())); 

    // When any button is clicked, call this->slotButtons() 
    connect(button1, SIGNAL(clicked()), this, SLOT(slotButtons())); 
    connect(button2, SIGNAL(clicked()), this, SLOT(slotButtons())); 
} 

// This slot is called when button1 is clicked. 
void MyWindow::slotButton1() 
{ 
    cout << "Button1 was clicked" << endl; 
} 

// This slot is called when button2 is clicked 
void MyWindow::slotButton2() 
{ 
    cout << "Button2 was clicked" << endl; 
} 

// This slot is called when any of the buttons were clicked 
void MyWindow::slotButtons() 
{ 
    cout << "A button was clicked" << endl; 
} 

int main() 
{ 
    MyWindow a; 
} 

resultados en:

[13:14:34 Mon May 02] ~/junkPrograms/src/nonsense $make 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.05/qt/mkspecs/linux-g++-64 -I. -I/opt/qtsdk-2010.05/qt/include/QtCore -I/opt/qtsdk-2010.05/qt/include/QtGui -I/opt/qtsdk-2010.05/qt/include -I. -I. -o signalsSlots.o signalsSlots.cpp 
g++ -m64 -Wl,-O1 -Wl,-rpath,/opt/qtsdk-2010.05/qt/lib -o nonsense signalsSlots.o -L/opt/qtsdk-2010.05/qt/lib -lQtGui -L/opt/qtsdk-2010.05/qt/lib -L/usr/X11R6/lib64 -lQtCore -lpthread 
signalsSlots.o: In function `MyWindow::MyWindow()': 
signalsSlots.cpp:(.text+0x1a2): undefined reference to `vtable for MyWindow' 
signalsSlots.cpp:(.text+0x1aa): undefined reference to `vtable for MyWindow' 
signalsSlots.o: In function `MyWindow::MyWindow()': 
signalsSlots.cpp:(.text+0x3e2): undefined reference to `vtable for MyWindow' 
signalsSlots.cpp:(.text+0x3ea): undefined reference to `vtable for MyWindow' 
signalsSlots.o: In function `main': 
signalsSlots.cpp:(.text+0x614): undefined reference to `vtable for MyWindow' 
signalsSlots.o:signalsSlots.cpp:(.text+0x61d): more undefined references to `vtable for MyWindow' follow 
collect2: ld returned 1 exit status 
make: *** [nonsense] Error 1 

vtable es para las funciones virtuales, que yo sepa, ¿cuál es la razón de error aquí?

+0

No veo cuál es el problema, pero me gustaría señalar que el tutorial que está utilizando está desactualizado. Te sugiero que consultes los tutoriales en la documentación de Qt 4.7. – ypnos

+0

@ypnos gracias pero el tut en 4.7 no muestra ningún ejemplo de "ejecución", que podría simplemente pegar y ejecutar :( –

+0

¿Posible duplicado de [Qt moc con implementaciones dentro de los archivos de encabezado?] (Http://stackoverflow.com/questions/3001615/qt- moc-with-implementations-inside-of-header-files) –

Respuesta

36

Parece que moc no genera código para su QObject porque lo declara en el archivo .cpp. La forma más fácil de arreglar eso es mover la declaración de MyWindow a una cabecera, y añadir la cabecera de la lista HEADERS, en el archivo .pro :

HEADERS += yourheader.h 

vuelva a ejecutar qmake.

(Tenga en cuenta que el libro de KDE 2.0 se mire es muy obsoleta)

+0

Gracias por responder, pero ¿no hay forma de que pueda mantener la declaración y la definición en el archivo .cpp? –

+0

Pruebe con HEADERS + = your.cpp. En general, aunque es posible, las declaraciones de QObject son tan dolorosas que prefiero tenerlas como encabezados (privados). Lo cual funciona bien con todos los buildsystems, ya sea qmake, cmake, ... –

+0

Gracias de nuevo, he separado el .h, .cpp y main: mad: y resolvió el error, yo aún no se han estudiado los detalles sobre el archivo moc. –

1

acaba de cambiar su principal() de la siguiente manera:

#include <QtGui/QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MyWindow w; 

    w.show(); 

    return a.exec(); 
} 
1

Basado en andref comentario justo por encima, cuando todo está en un archivo CPP como stuff.cpp, es necesario agregar al final del archivo:

#include "moc_stuff.cpp" 

(esto es con Qt 4.7.0)

+0

Usando Qt 4.8, esto no funcionó para mí. Tenía que hacer lo que sugiere el comentario referido. – Tshepang

22

Tal vez demasiado tarde, pero ... Tuve el mismo problema y luché por un tiempo para encontrar de dónde viene.

Haga clic derecho en su proyecto y seleccione "Ejecutar qhacer" para una nueva compilación de clases MOC. Por lo general, se ejecuta automáticamente ...

El compilador moc genera los talones y llama en moc_xxxx.cpp, y genera la materia vtable

+0

No uso qtcreator. Funciono qmake muchas veces antes de preguntar aquí. No ayudó. –

+0

@AnishaKaul Del mismo modo. Ejecutar 'qmake' para mí no soluciona nada. Si ejecuto 'qmake --project', entonces se regenera el' .pro' y puedo compilar, pero eso manguera todos los cambios que la gente ha hecho al '.pro', que es realmente malo. –

+2

1 ++ esto soluciona mi problema – Ivan

0

Este problema puede ser causado por alguna de las siguientes razones. Me he tropezado con todos ellos de vez en cuando.


En el encabezado de su clase puede faltar la macro Q_OBJECT. Agregue la macro al encabezado como ya se señaló por otras respuestas.

class MyWidg : public QWidget 
{ 
    Q_OBJECT 

Su cabecera de la clase no puede ser analizado por el Ministerio de Comercio. Agregue el archivo de encabezado en las definiciones HEADERS de su archivo de proyecto .pro (o .pri).

HEADERS += file.h 

Si nada de lo anterior es cierto, entonces es probable que tenga que ejecutar qmake de nuevo para asegurarse moc analiza el encabezado de nuevo, por si acaso se añadió la macro Q_OBJECT en la cabecera después de la qmake era correr. Simplemente ejecuta qmake nuevamente.

Cuestiones relacionadas