PDA

View Full Version : Signals and Slots - Moc QObject Problem



GBayo1
22nd March 2010, 14:12
Hi all,

I was wondering would someone be able to help me with a slight problem. I am trying to use signals and slots within my program. From QT, we know that “all classes that contain signals or slots must mention Q_OBJECT at the top of their declaration. They must also derive (directly or indirectly) from QObject”. That’s fine. So the following is an example I’m trying to implement, taken directly from http://doc.trolltech.com/4.6/signalsandslots.html

Counter.h

#include <QObject>

class Counter : public QObject
{
Q_OBJECT

public:
Counter() { m_value = 0; }

int value() const { return m_value; }

public slots:
void setValue(int value);

signals:
void valueChanged(int newValue);

private:
int m_value;
};

Counter.cpp

#include “Counter.h”

void Counter::setValue(int value)
{
if (value != m_value) {
m_value = value;
emit valueChanged(value);
}
}

Then when trying to instantiate the class:

Counter a, b;
QObject::connect(&a, SIGNAL(valueChanged(int)),
&b, SLOT(setValue(int)));

a.setValue(12); // a.value() == 12, b.value() == 12
b.setValue(48); // a.value() == 12, b.value() == 48

I get the following linking errors:

error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Counter::metaObject(void)const " (?metaObject@Counter@@UBEPBUQMetaObject@@XZ)
error LNK2001: unresolved external symbol "public: virtual void * __thiscall Counter::qt_metacast(char const *)" (?qt_metacast@Counter@@UAEPAXPBD@Z)
error LNK2001: unresolved external symbol "public: virtual int __thiscall Counter::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Counter@@UAEHW4Call@QMetaObject@@HPA PAX@Z)
error LNK2001: unresolved external symbol "protected: void __thiscall Counter::valueChanged(int)" (?valueChanged@Counter@@IAEXH@Z)

From looking at forums (http://lists.trolltech.com/qt-interest/2005-12/msg00374.html), it seems that we need to moc the source – “You need to call "moc" on your Counter header file and make sure the compiler includes the output of moc into the binary. How you'd do that depends on the compiler being used and if you use custom Makefiles, qmake-projects or something else“.

As far as I can see, I have a moc file and it is being updated. Would someone please help me with this probelm and let us know how to overcome it.

Thank you for your time

JohannesMunk
22nd March 2010, 15:06
I made sure: Your code is fine. Works for me:



signalslot.pro:

QT += core
TARGET = signalslot
TEMPLATE = app
HEADERS += Counter.h
SOURCES += main.cpp

counter.h:

#ifndef COUNTER_H
#define COUNTER_H

#include <QObject>
#include <QDebug>

class Counter : public QObject
{ Q_OBJECT
public:
Counter() { m_value = 0; }

int value() const { return m_value; }

public slots:
void setValue(int value)
{
if (value != m_value) {
m_value = value;
emit valueChanged(value);
qDebug() << "ValueChanged: " << value;
}
}

signals:
void valueChanged(int newValue);

private:
int m_value;
};


#endif // COUNTER_H

main.cpp:

#include <QApplication>
#include "Counter.h"
#include <QDebug>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

Counter a, b;
QObject::connect(&a, SIGNAL(valueChanged(int)),&b, SLOT(setValue(int)));

a.setValue(12); // a.value() == 12, b.value() == 12
b.setValue(48); // a.value() == 12, b.value() == 48

return 0;//a.exec();
}

Output:
ValueChanged: 12
ValueChanged: 12
ValueChanged: 48

Try deleting the makefiles. clean the project.

What environment are you using? QtCreator?

Johannes

zgulser
22nd March 2010, 15:26
I can suggest you to put your connections at the end of the scope

JohannesMunk
22nd March 2010, 15:43
?

Connections at the end of the scope, might be a useful advice inside a constructor. But if we would establish the connection in this example after the calls to setValue.. the test program would not work as expected.

However that might be, it won't solve the original problem..

Joh

GBayo1
22nd March 2010, 16:25
Thank you for your rapid response.

The environment question is a little tricky. We are working on a project using the H3D API (for haptics). We have QT integrated within H3D for the GUI part and running the program from Visual Studio 2008. Our GUI requirements are quite simple so therefore we are not using QTCreator or anything similar. All we are doing is deriving from a H3D window class and using some simple windows and buttons. I'm not too sure if you have experience with H3D but it could be the way we have QT integrated within H3D.

Is there any informatin I can provide you with that might help you understand where the probelm lies??

JohannesMunk
22nd March 2010, 16:47
Hi!

I am out of my depth here. But I would guess your signal slot problem is probably not a question of the H3D API. Or does the problem only occur in a test project, once you include H3d?

Otherwise I think, its a problem of your Qt integration into Visual Studio.

Good luck!

Johannes

minimoog
22nd March 2010, 17:35
Is moc'ed .obj file added to a linker? In this case it wiil be moc_counter.obj.