PDA

View Full Version : Getting a timer's thing to work....



hakermania
3rd June 2011, 12:10
Hello, this is a terminal application i'm trying to make:


#include <QtCore/QTimer>
#include <QCoreApplication>
#include <QtCore/QObject>
#include <QtCore/QDebug>

class checker : public QObject
{
Q_OBJECT
public:
checker(QObject * o = 0) : QObject(o) {}

public slots:
void check() {
qDebug() << "i am going through the check() function right now!\n";
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer * timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()),new checker(timer), SLOT(checker::check()));
timer->start(1000);
return a.exec();
}


I get this error:


error: undefined reference to `vtable for checker'


Can anybody explain me why?
Thanks a lot!

cincirin
3rd June 2011, 12:22
Try to implement check function in source code, not in header

stampede
3rd June 2011, 12:25
meta object code for class is not generated, you'll need to call moc on this source yourself:


moc file.cpp >> moc_file.cpp

and include this file in your source:


int main{...}

#include "moc_file.cpp"


edit:
SLOT statement is wrong, you should not include class name, only method name:


QObject::connect(timer, SIGNAL(timeout()),new checker(timer), SLOT(check()));
// not checker::check(), because it will lead to checker::checker::check() in the end :)

hakermania
3rd June 2011, 13:09
Thanks for your suggestions!
stampede, when should I run the 'moc' command? Before compiling, right?
But still, I get flood of error messages:

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp
In file included from main.cpp:5:0:
moc_main.cpp:42:19: error: ‘checker’ has not been declared
moc_main.cpp:51:20: error: ‘checker’ has not been declared
moc_main.cpp:51:42: error: non-member function ‘const QMetaObject* metaObject()’ cannot have cv-qualifier
/usr/include/qt4/QtCore/qobject.h: In function ‘const QMetaObject* metaObject()’:
/usr/include/qt4/QtCore/qobject.h:296:33: error: ‘QScopedPointer<QObjectData> QObject::d_ptr’ is protected
moc_main.cpp:53:21: error: within this context
/usr/include/qt4/QtCore/qobject.h:296:33: error: invalid use of non-static data member ‘QObject::d_ptr’
moc_main.cpp:53:21: error: from this location
/usr/include/qt4/QtCore/qobject.h:296:33: error: ‘QScopedPointer<QObjectData> QObject::d_ptr’ is protected
moc_main.cpp:53:50: error: within this context
/usr/include/qt4/QtCore/qobject.h:296:33: error: invalid use of non-static data member ‘QObject::d_ptr’
moc_main.cpp:53:50: error: from this location
moc_main.cpp: At global scope:
moc_main.cpp:56:7: error: ‘checker’ has not been declared
moc_main.cpp: In function ‘void* qt_metacast(const char*)’:
moc_main.cpp:60:47: error: expected type-specifier before ‘checker’
moc_main.cpp:60:47: error: expected ‘>’ before ‘checker’
moc_main.cpp:60:47: error: expected ‘(’ before ‘checker’
moc_main.cpp:60:47: error: ‘checker’ was not declared in this scope
moc_main.cpp:60:55: error: expected primary-expression before ‘>’ token
moc_main.cpp:60:57: error: invalid use of ‘this’ in non-member function
moc_main.cpp:60:63: error: expected ‘)’ before ‘;’ token
moc_main.cpp:61:40: error: cannot call member function ‘virtual void* QObject::qt_metacast(const char*)’ without object
moc_main.cpp: At global scope:
moc_main.cpp:64:5: error: ‘checker’ has not been declared
moc_main.cpp: In function ‘int qt_metacall(QMetaObject::Call, int, void**)’:
moc_main.cpp:66:43: error: cannot call member function ‘virtual int QObject::qt_metacall(QMetaObject::Call, int, void**)’ without object
moc_main.cpp:71:23: error: ‘check’ was not declared in this scope
moc_main.cpp: In function ‘void* qt_metacast(const char*)’:
moc_main.cpp:62:1: warning: control reaches end of non-void function
moc_main.cpp: In function ‘const QMetaObject* metaObject()’:
moc_main.cpp:54:1: warning: control reaches end of non-void function
make: *** [main.o] Error 1

stampede
3rd June 2011, 13:14
Yes, before compilation, redirect the moc output to file, and include this file in your source. I've just tried with your source code, it worked ok.
If you want to make it done automatically, create a header, add it to HEADERS list in .pro file and put the class definition there.
edit:
remember to include "moc_main.cpp" AFTER the class declaration, if you want to do it this way

squidge
3rd June 2011, 20:52
Or you could just put #include "foo.moc" at the end of your source file and run QMake, then it'll do it all for you automatically, including running MOC. foo is the name of your source file.

DanH
4th June 2011, 02:34
I think the main problem you have is that the slot function check() is implemented as an "inline" rather than a separate method. This is OK for regular methods, but not slots, due to the way the MOC compiler works. Try something like this:

class checker : public QObject
{
Q_OBJECT
public:
checker(QObject * o = 0) : QObject(o) {}

public slots:
void check();
};

void checker::check() {
qDebug() << "i am going through the check() function right now!\n";
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer * timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()),new checker(timer), SLOT(checker::check()));
timer->start(1000);
return a.exec();
}

(And, of course, fix your connect().)

wysota
4th June 2011, 06:51
I think the main problem you have is that the slot function check() is implemented as an "inline" rather than a separate method.
Hmm.... really?

This is OK for regular methods, but not slots, due to the way the MOC compiler works.
Would you care to explain?


#include <QtCore>


class Dummy : public QObject {
Q_OBJECT
public:
Dummy() : QObject() {
connect(this, SIGNAL(sig()), this, SLOT(print()));
}
void emitASignal() { emit sig(); }
public slots:
inline void print() {
qDebug() << Q_FUNC_INFO;
}

signals:
void sig();

};

#include "main.moc"

int main(int argc, char **argv){
Dummy d;
d.emitASignal();
return 0;
}

Result:

$ ./test
void Dummy::print()

DanH
4th June 2011, 13:35
What happens if you move the connect() call into main?

wysota
4th June 2011, 22:05
It works, of course.


#include <QtCore>


class Dummy : public QObject {
Q_OBJECT
public:
Dummy() : QObject() {
// connect(this, SIGNAL(sig()), this, SLOT(print()));
}
void emitASignal() { emit sig(); }
public slots:
inline void print() {
qDebug() << Q_FUNC_INFO;
}

signals:
void sig();

};

#include "main.moc"

int main(int argc, char **argv){
Dummy d;
QObject::connect(&d, SIGNAL(sig()), &d, SLOT(print()));
d.emitASignal();
return 0;
}


$ ./test
void Dummy::print()