Qt:信号和插槽错误:未定义的引用' vtable for



以下链接中的示例: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;
}

结果:

    [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是用于虚函数的,问一下,这里出现错误的原因是什么?

看起来moc不会为您的QObject生成代码,因为您在.cpp文件中声明了它。修复该问题的最简单方法是将MyWindow的声明移动到标题中,并将标题添加到HEADERS列表中,在中。箴文件:

HEADERS += yourheader.h 

然后重新运行qmake

(请注意,您所看的KDE 2.0的书是非常过时的)

也许太晚了,但是…我也遇到过同样的问题,我花了一段时间才找到它的来源。

右键单击您的项目,并选择"运行qmake",以获得MOC类的新构建。它通常会自动运行…

moc编译器生成moc_xxxx.cpp中的存根和调用,并生成虚表

按如下方式修改Main():

#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWindow w;
    w.show();
    return a.exec();
}

根据上面的andref注释,当所有内容都在一个cpp文件中(如stuff.cpp)时,您需要在文件末尾添加:

#include "moc_stuff.cpp"

(这是在Qt 4.7.0)

此问题可能由以下几种原因引起。我偶尔也会碰到这些问题。


类头可能缺少Q_OBJECT宏。将宏添加到标题中,正如其他答案所指出的那样。

class MyWidg : public QWidget
{
    Q_OBJECT

你的类头可能不会被moc解析。在.pro(或.pri)项目文件的头文件定义中添加头文件。

HEADERS += file.h

如果以上都不成立,那么您可能需要再次运行qmake以确保moc再次解析头文件,以防qmake运行后在头文件中添加了Q_OBJECT宏。

最新更新