qt signals-slots vtable undefined-reference

Qt: Señales y ranuras Error: referencia indefinida a `vtable para



signals-slots undefined-reference (5)

Siguiendo el ejemplo de este enlace: http://developer.kde.org/documentation/books/kde-2.0-development/ch03lev1sec3.html

#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 funciones virtuales, AFAIK, ¿cuál es la razón del error aquí?


Basado en el comentario de andref que se encuentra arriba, cuando todo está en un archivo cpp como stuff.cpp , debe agregar al final del archivo:

#include "moc_stuff.cpp"

(esto es con Qt 4.7.0)


Este problema puede ser causado por algunas de las siguientes razones. He tropezado con todos ellos de vez en cuando.

A su encabezado de clase le puede faltar la macro Q_OBJECT. Agregue la macro al encabezado como ya se señaló en otras respuestas.

class MyWidg : public QWidget { Q_OBJECT

El encabezado de su clase no puede ser analizado por el moc. 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 probablemente deba ejecutar qmake nuevamente para asegurarse de que moc analiza el encabezado nuevamente, en caso de que la macro Q_OBJECT se haya agregado en el encabezado después de ejecutar el qmake. Solo ejecuta qmake de nuevo.


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

HEADERS += yourheader.h

Luego vuelva a ejecutar qmake .

(Tenga en cuenta que el libro de KDE 2.0 que mira está muy desactualizado)


Solo cambia tu 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(); }


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 qmake" para una nueva compilación de clases MOC. Por lo general, se ejecuta automáticamente ...

El compilador moc genera los apéndices y las llamadas en moc_xxxx.cpp, y genera las cosas vtable