今天寫了Qt內建的Demo的一個執行個體,總是會出現undefined reference to `vtable for的錯誤,查了一些網上的資料終於知道哪裡出錯了,自己做個記載,直接放上代碼,代碼中間注釋說明了錯誤的原因
#include <QtCore>#include <QtGui>class Pixmap : public QGraphicsWidget{ Q_OBJECTpublic: Pixmap(const QPixmap &pix, QGraphicsItem *parent = 0) : QGraphicsWidget(parent), orig(pix), p(pix) { } void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { painter->drawPixmap(QPointF(), p); } virtual void mousePressEvent(QGraphicsSceneMouseEvent * ) { emit clicked(); } virtual void setGeometry(const QRectF &rect) { QGraphicsWidget::setGeometry(rect); if (rect.size().width() > orig.size().width()) p = orig.scaled(rect.size().toSize()); else p = orig; }Q_SIGNALS: void clicked();private: QPixmap orig; QPixmap p;};class GraphicsView : public QGraphicsView{ Q_OBJECTpublic: GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) : QGraphicsView(scene, parent) { } virtual void resizeEvent(QResizeEvent *event) { fitInView(sceneRect(), Qt::KeepAspectRatio); }};void createStates(const QObjectList &objects, const QRect &selectedRect, QState *parent){ for (int i = 0; i < objects.size(); ++i) { QState *state = new QState(parent); state->assignProperty(objects.at(i), "geometry", selectedRect); parent->addTransition(objects.at(i), SIGNAL(clicked()), state); }}void createAnimations(const QObjectList &objects, QStateMachine *machine){ for (int i=0; i<objects.size(); ++i) machine->addDefaultAnimation(new QPropertyAnimation(objects.at(i), "geometry"));}#include "main.moc" /*:qmake 不會處理.cpp檔案裡的Q_OBJECT, *所以,如果在.cpp檔案中有它的話, *也會產生undefined reference to vtable for "xxx::xxx". *這時,需要先用moc xxxx.cpp產生相應的moc檔案,再包含到.cpp裡面去, *才能解決這個問題. **/int main(int argc, char **argv){ Q_INIT_RESOURCE(appchooser); QApplication app(argc, argv); Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png")); Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png")); Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png")); Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png")); p1->setObjectName("p1"); p2->setObjectName("p2"); p3->setObjectName("p3"); p4->setObjectName("p4"); p1->setGeometry(QRectF( 0.0, 0.0, 64.0, 64.0)); p2->setGeometry(QRectF(236.0, 0.0, 64.0, 64.0)); p3->setGeometry(QRectF(236.0, 236.0, 64.0, 64.0)); p4->setGeometry(QRectF( 0.0, 236.0, 64.0, 64.0)); QGraphicsScene scene(0, 0, 300, 300); scene.setBackgroundBrush(Qt::white); scene.addItem(p1); scene.addItem(p2); scene.addItem(p3); scene.addItem(p4); GraphicsView window(&scene); window.setFrameStyle(0); window.setAlignment(Qt::AlignLeft | Qt::AlignTop); window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); QState *group = new QState(&machine); group->setObjectName("group"); QRect selectedRect(86, 86, 128, 128); QState *idleState = new QState(group); group->setInitialState(idleState); QObjectList objects; objects << p1 << p2 << p3 << p4; createStates(objects, selectedRect, group); createAnimations(objects, &machine); machine.setInitialState(group); machine.start();#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) window.showMaximized();#else window.resize(300, 300); window.show();#endif return app.exec();}
注意 #include “main.moc" 是因為這是main.cpp 所以產生的是main.moc , #include"main.moc” 一定要寫在後面,也可以寫在最後的位置,不能寫在開始位置,