看到未定义的引用`vtable for CollidingMice'
seeing undefined reference to `vtable for CollidingMice'
我正在修改 Qt 代码附带的 Qt 示例 'collidingmice'。
在原始源代码中,QApplication 包含 QView 和 QScene,但我制作了一个包含 QView 和 QScene 的 class CollidingMice 以使用键盘输入杀死视图和场景。我想将键盘输入发送到 CollidingMice class。
我在堆栈溢出中阅读了 4 或 5 个关于 'undefined reference to vtable for..' 的问题,但找不到适合我的案例。我查了一下
1.父classes中没有未定义的虚函数
2. 我尝试添加析构函数的定义 ~CollidingMices() {}
3. 我 99% 确定下面的 CollidingMice 代码中没有未定义的成员函数。
#include "mouse.h"
#include <QtGui>
#include <math.h>
static const int MouseCount = 7;
class CollidingMice : public QMainWindow
{
Q_OBJECT
private:
QGraphicsView *view;
QGraphicsScene scene;
QTimer *timer;
public:
CollidingMice(QWidget *parent = 0): QMainWindow(parent) {
scene.setSceneRect(-300, -300, 600, 600);
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
for (int i = 0; i < MouseCount; ++i) {
Mouse *mouse = new Mouse;
mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
::cos((i * 6.28) / MouseCount) * 200);
scene.addItem(mouse);
}
view = new QGraphicsView(this);
view->setRenderHint(QPainter::Antialiasing);
view->setBackgroundBrush(QPixmap(":/images/cheese.jpg"));
view->setCacheMode(QGraphicsView::CacheBackground);
view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
view->setDragMode(QGraphicsView::ScrollHandDrag);
view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) || defined(Q_WS_SIMULATOR)
view->showMaximized();
#else
view->resize(600, 450);
view->move(30,30);
view->show();
#endif
timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()), &scene, SLOT(advance()));
timer->start(1000 / 33);
}
private:
void keyPressEvent(QKeyEvent *event);
};
void CollidingMice::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_q) {
close();
}
}
int collidingmice_main(int argc, char **argv)
{
QApplication app(argc, argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
CollidingMice w;
return app.exec();
}
添加和编辑:按照 svlasov 告诉我的那样删除上面的 QOBJECT 之后,并按如下方式修复构造函数之后(请参阅 setScene.. 我的同事建议我。)
view = new QGraphicsView(this);
view->resize(600,500);
view->setScene(&scene);
view->setRenderHint(QPainter::Antialiasing);
我可以编译并执行它。
您的 class 似乎是在 .cpp 中声明的,而不是 .h
Qt MOC 不喜欢它。您可以在文件末尾添加 #include "mysrcfile_moc.cpp"
或将 class 声明移动到 mysrcfile.h 之后不要忘记清理和重建。
如果您在 class 定义中使用 Q_OBJECT
,您必须将 class 提取到单独的头文件中。
如果您不在 CollidingMice
class 中声明信号和槽,只需删除 Q_OBJECT
即可编译。
更新
正如@KubaOber 评论的那样,您可以简单地在 file.cpp
文件的末尾添加:
#include "file.moc"
和qmake
将完成所有工作。
您的代码有 3 个问题...
Qt 解析 class header 并构造与 QObject 层次结构相关的底层函数,包括用于导出的符号。这是一个基本的解析器,需要一个显式的 header 文件——既是为了便于解析,也是为了符号导出。 创建一个 header - 相信我,创建一个文件需要 5 秒,cut-paste class 声明并将其包含回去...并节省大量时间来解决 Qt 编译问题。
场景有一个场景矩形,但视图是一个常规 QWidget - 这意味着 Window 应该使用布局 class 并将其包含在其他 QWidget 中。如果做不到这一点,视图将被调整为类似于 QSize(1,1) 的大小,并且默认位于 pos(0, 0)。这就是你看不到它的原因。
对于 QGraphicsScene,您正在寻找插槽 update()
而不是 advance()
我正在修改 Qt 代码附带的 Qt 示例 'collidingmice'。
在原始源代码中,QApplication 包含 QView 和 QScene,但我制作了一个包含 QView 和 QScene 的 class CollidingMice 以使用键盘输入杀死视图和场景。我想将键盘输入发送到 CollidingMice class。
我在堆栈溢出中阅读了 4 或 5 个关于 'undefined reference to vtable for..' 的问题,但找不到适合我的案例。我查了一下
1.父classes中没有未定义的虚函数
2. 我尝试添加析构函数的定义 ~CollidingMices() {}
3. 我 99% 确定下面的 CollidingMice 代码中没有未定义的成员函数。
#include "mouse.h"
#include <QtGui>
#include <math.h>
static const int MouseCount = 7;
class CollidingMice : public QMainWindow
{
Q_OBJECT
private:
QGraphicsView *view;
QGraphicsScene scene;
QTimer *timer;
public:
CollidingMice(QWidget *parent = 0): QMainWindow(parent) {
scene.setSceneRect(-300, -300, 600, 600);
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
for (int i = 0; i < MouseCount; ++i) {
Mouse *mouse = new Mouse;
mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
::cos((i * 6.28) / MouseCount) * 200);
scene.addItem(mouse);
}
view = new QGraphicsView(this);
view->setRenderHint(QPainter::Antialiasing);
view->setBackgroundBrush(QPixmap(":/images/cheese.jpg"));
view->setCacheMode(QGraphicsView::CacheBackground);
view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
view->setDragMode(QGraphicsView::ScrollHandDrag);
view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) || defined(Q_WS_SIMULATOR)
view->showMaximized();
#else
view->resize(600, 450);
view->move(30,30);
view->show();
#endif
timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()), &scene, SLOT(advance()));
timer->start(1000 / 33);
}
private:
void keyPressEvent(QKeyEvent *event);
};
void CollidingMice::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_q) {
close();
}
}
int collidingmice_main(int argc, char **argv)
{
QApplication app(argc, argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
CollidingMice w;
return app.exec();
}
添加和编辑:按照 svlasov 告诉我的那样删除上面的 QOBJECT 之后,并按如下方式修复构造函数之后(请参阅 setScene.. 我的同事建议我。)
view = new QGraphicsView(this);
view->resize(600,500);
view->setScene(&scene);
view->setRenderHint(QPainter::Antialiasing);
我可以编译并执行它。
您的 class 似乎是在 .cpp 中声明的,而不是 .h
Qt MOC 不喜欢它。您可以在文件末尾添加 #include "mysrcfile_moc.cpp"
或将 class 声明移动到 mysrcfile.h 之后不要忘记清理和重建。
如果您在 class 定义中使用 Q_OBJECT
,您必须将 class 提取到单独的头文件中。
如果您不在 CollidingMice
class 中声明信号和槽,只需删除 Q_OBJECT
即可编译。
更新
正如@KubaOber 评论的那样,您可以简单地在 file.cpp
文件的末尾添加:
#include "file.moc"
和qmake
将完成所有工作。
您的代码有 3 个问题...
Qt 解析 class header 并构造与 QObject 层次结构相关的底层函数,包括用于导出的符号。这是一个基本的解析器,需要一个显式的 header 文件——既是为了便于解析,也是为了符号导出。 创建一个 header - 相信我,创建一个文件需要 5 秒,cut-paste class 声明并将其包含回去...并节省大量时间来解决 Qt 编译问题。
场景有一个场景矩形,但视图是一个常规 QWidget - 这意味着 Window 应该使用布局 class 并将其包含在其他 QWidget 中。如果做不到这一点,视图将被调整为类似于 QSize(1,1) 的大小,并且默认位于 pos(0, 0)。这就是你看不到它的原因。
对于 QGraphicsScene,您正在寻找插槽
update()
而不是advance()