Qt:信号和槽错误:未定义对“vtable”的引用
以下链接中的示例: 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 用于虚拟函数,AFAIK,这里错误的原因是什么?
Following example from this link: 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看起来 moc 不会为您的
QObject
生成代码,因为您在.cpp
文件中声明了它。解决此问题的最简单方法是将MyWindow
的声明移至标头,并将标头添加到 .proHEADERS 列表中> 文件:然后重新运行
qmake
。(请注意,您查看的 KDE 2.0 书籍已经过时了)
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 ofMyWindow
to a header, and add the header to theHEADERS
list, in the .pro file:Then rerun
qmake
.(Please note that the KDE 2.0 book you look at is vastly outdated)
也许为时已晚,但是......遇到了同样的问题,并努力寻找它的来源。
右键单击您的项目并选择“运行 qmake”以生成 MOC 类的新版本。它通常会自动运行...
moc 编译器在 moc_xxxx.cpp 中生成存根和调用,并生成 vtable 内容
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...
The moc compiler generates the stubs and calls in moc_xxxx.cpp, and generates the vtable stuff
只需更改您的 Main() 如下:
Just Change your Main() as follows:
根据上面的 andref 注释,当所有内容都在一个 cpp 文件中(例如
stuff.cpp
)时,您需要在文件末尾添加:(这是 Qt 4.7.0 的情况)
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:(this is with Qt 4.7.0)
此问题可能是由以下某些原因引起的。我时不时地偶然发现了所有这些。
您的类头可能缺少 Q_OBJECT 宏。正如其他答案已经指出的那样,将宏添加到标题中。
moc 可能无法解析您的类标头。在 .pro(或 .pri)项目文件的 HEADERS 定义中添加头文件。
如果以上情况都不成立,那么您可能需要再次运行 qmake 以确保 moc 再次解析标头,以防在运行 qmake 后在标头中添加 Q_OBJECT 宏。再次运行 qmake 即可。
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.
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.
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.