0

I'm modifying a Qt example 'collidingmice' which comes with the Qt code.
In the original source, the QApplication contains QView and QScene, but I made a class CollidingMice containing the QView and QScene to kill the view and scene using keyboard input. I want to send the keyboard input to CollidingMice class. I read 4 or 5 questions in stack overflow about 'undefined reference to vtable for..' but could not find the case that fits me. I checked that
1. there is no virtual function in the parent classes that is not defined.
2. I tried adding definition of destructor ~CollidingMices() {}
3. and I'm 99% sure there is no undefined member function in the CollidingMice code below.

#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();
}

ADD and EDIT : After deleting the QOBJECT above as svlasov told me to, and after fixing the constructor as below (see the setScene..my colleage suggested me.)

               view = new QGraphicsView(this);
                view->resize(600,500);
                view->setScene(&scene);
                view->setRenderHint(QPainter::Antialiasing);

I could compile it and execute it.

enter image description here

Chan Kim
  • 5,177
  • 12
  • 57
  • 112

3 Answers3

2

If you use Q_OBJECT in class definition you have to extract the class into separate header file.

If you don't declare signals and slots in CollidingMice class, just remove Q_OBJECT and it will compile.

UPDATE

As @KubaOber commented, you can simply include to the end of your file.cpp file:

#include "file.moc"

and qmake will do all the job.

svlasov
  • 9,923
  • 2
  • 38
  • 39
1

It seems your class is declared in .cpp rather than .h

Qt MOC doesn't like it. You may add #include "mysrcfile_moc.cpp" at the end of the file or move the class declaration to mysrcfile.h Don't forget to clean & rebuild after that.

Matt
  • 13,674
  • 1
  • 18
  • 27
1

There are 3 issues with your code...

  1. Qt parses the class header and constructs underlying functions related to QObject hierarchy, including symbols for export. This is a rudimentary parser and needs an explicit header file - both for ease of parsing and for symbol export. Create a header - trust me, it's 5 seconds of work to create a file, cut-paste the class declaration and include it back... and saves a lot of time troubleshooting Qt compile issues.

  2. the scene has a scene rectangle, but the view is a regular QWidget - which means the Window should use a layout class and include it in like other QWidgets. Failing this, the view will be sized to something like QSize(1,1) and located at pos(0, 0) by default. This is why you can't see it.

  3. For the QGraphicsScene, you're looking for the slot update() and not advance()

Fox
  • 2,078
  • 17
  • 18
  • ok, at least it compiles now but after changing it to 'view = new GraphicsView(&scene);' the window size is ok less the mice and cheese pictures. I'll post the new capture in a second. – Chan Kim Mar 26 '15 at 00:09