Qt:信号与槽错误:未定义的虚表

时间:2022-10-08 04:54:23

Following example from this link: http://developer.kde.org/documentation/books/kde-2.0-development/ch03lev1sec3.html

下面是这个链接的示例: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;
}

results in:

结果:

    [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 is for virtual functions, AFAIK, what's the reason of error here?

vtable是虚拟函数,AFAIK,这里出错的原因是什么?

5 个解决方案

#1


36  

It looks like moc doesn't generate code for your QObject because you declare it in the .cpp file. The easiest way to fix that is to move the declaration of MyWindow to a header, and add the header to the HEADERS list, in the .pro file:

看起来moc不会为你的QObject生成代码,因为你在.cpp文件中声明了它。解决这个问题的最简单方法是将MyWindow的声明移到header中,并在.pro文件中添加标题列表。

HEADERS += yourheader.h 

Then rerun qmake.

然后重新运行qmake。

(Please note that the KDE 2.0 book you look at is vastly outdated)

(请注意,你看的KDE 2.0版书已经过时了)

#2


22  

Maybe too late but... Had the same issue and fighted for a while to find where it comes from.

也许太迟了但是…有了同样的问题,并进行了一段时间的斗争来找出它的来源。

Right click on your project and select “Run qmake” to for a new build of MOC classes. It usually does run automatically...

右键单击您的项目,并选择“Run qmake”来构建新的MOC类。它通常是自动运行的…

The moc compiler generates the stubs and calls in moc_xxxx.cpp, and generates the vtable stuff

moc编译器在moc_xxxx中生成存根和调用。生成vtable内容。

#3


1  

Just Change your Main() as follows:

只需改变你的Main()如下:

#include <QtGui/QApplication>

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

    w.show();

    return a.exec();
}

#4


1  

Based on andref comment just above, when everything is in one cpp file like stuff.cpp, you need to add at the end of the file:

基于andref的评论,当一切都在一个cpp文件的时候。cpp,你需要在文件的末尾加上:

#include "moc_stuff.cpp"

(this is with Qt 4.7.0)

(这是Qt 4.7.0)

#5


0  

This issue may be caused by some of the following reasons. I have stumbled on all of them from time to time.

这个问题可能是由以下几个原因引起的。我偶尔会碰到他们。


Your class header may be missing the Q_OBJECT macro. Add the macro to the header as already noted by other answers.

您的类头可能丢失了Q_OBJECT宏。将宏添加到header中,就像已经注意到的其他答案一样。

class MyWidg : public QWidget
{
    Q_OBJECT

Your class header may not be parsed by the moc. Add the header file in the HEADERS definitions of your .pro (or .pri) project file.

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

HEADERS += file.h

If none of the above is true, then you probably need to run qmake again to make sure moc parses the header again, just in case the Q_OBJECT macro was added in the header after the qmake was run. Just run qmake again.

如果以上内容都不正确,那么您可能需要再次运行qmake,以确保moc再次解析报头,以防在qmake运行后在header中添加Q_OBJECT宏。再次运行qmake。

#1


36  

It looks like moc doesn't generate code for your QObject because you declare it in the .cpp file. The easiest way to fix that is to move the declaration of MyWindow to a header, and add the header to the HEADERS list, in the .pro file:

看起来moc不会为你的QObject生成代码,因为你在.cpp文件中声明了它。解决这个问题的最简单方法是将MyWindow的声明移到header中,并在.pro文件中添加标题列表。

HEADERS += yourheader.h 

Then rerun qmake.

然后重新运行qmake。

(Please note that the KDE 2.0 book you look at is vastly outdated)

(请注意,你看的KDE 2.0版书已经过时了)

#2


22  

Maybe too late but... Had the same issue and fighted for a while to find where it comes from.

也许太迟了但是…有了同样的问题,并进行了一段时间的斗争来找出它的来源。

Right click on your project and select “Run qmake” to for a new build of MOC classes. It usually does run automatically...

右键单击您的项目,并选择“Run qmake”来构建新的MOC类。它通常是自动运行的…

The moc compiler generates the stubs and calls in moc_xxxx.cpp, and generates the vtable stuff

moc编译器在moc_xxxx中生成存根和调用。生成vtable内容。

#3


1  

Just Change your Main() as follows:

只需改变你的Main()如下:

#include <QtGui/QApplication>

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

    w.show();

    return a.exec();
}

#4


1  

Based on andref comment just above, when everything is in one cpp file like stuff.cpp, you need to add at the end of the file:

基于andref的评论,当一切都在一个cpp文件的时候。cpp,你需要在文件的末尾加上:

#include "moc_stuff.cpp"

(this is with Qt 4.7.0)

(这是Qt 4.7.0)

#5


0  

This issue may be caused by some of the following reasons. I have stumbled on all of them from time to time.

这个问题可能是由以下几个原因引起的。我偶尔会碰到他们。


Your class header may be missing the Q_OBJECT macro. Add the macro to the header as already noted by other answers.

您的类头可能丢失了Q_OBJECT宏。将宏添加到header中,就像已经注意到的其他答案一样。

class MyWidg : public QWidget
{
    Q_OBJECT

Your class header may not be parsed by the moc. Add the header file in the HEADERS definitions of your .pro (or .pri) project file.

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

HEADERS += file.h

If none of the above is true, then you probably need to run qmake again to make sure moc parses the header again, just in case the Q_OBJECT macro was added in the header after the qmake was run. Just run qmake again.

如果以上内容都不正确,那么您可能需要再次运行qmake,以确保moc再次解析报头,以防在qmake运行后在header中添加Q_OBJECT宏。再次运行qmake。