PDA

View Full Version : [newbie] signal/slot with sublassing problem



borker
16th April 2009, 15:48
Hi everyone, this is probably a newbie question, but I couldn't readily find an answer so would like to ask the group for help.

I have a class hierarchy like the following:


namespace A {
class GenericService {
public :
void sendQuery();

protected slot:
void receiveData(QByteArray &data);
}
}

void GenericService::sendQuery()
{
/* do a bunch of stuff that results in a query being sent through RemoteService */

connect (RemoteService, SIGNAL(data(QByteArray)), this, SLOT(receiveData(QByteArray));

}

namespace B {
class SomeServiceType : public GenericService {
public :
/* some specialized functions */
}

class MoreSpecificServiceType : public SomeServiceType {
public :
/* more specialized functions */
}
}


My problem is that when I execute a query from an instance of MoreSpecificServiceType the connect fails to find the slot B::SomeServiceType::receiveData unless I specifically create that function, which then hides the default behavior of A::GenericService::receiveData which is what I want to have actually handle this signal. I'd have thought that the specialized classes would inherit the appropriate slot from the original base class and I'd not need to reimplement it. Can anyone let me know what the correct approach here is? or have I just made a general mistake someone can point out?

many thanks for your help
Nathan

caduel
16th April 2009, 17:06
The issue is probably that you need to explicitly qualify the namespace in the SIGNAL/SLOT signatures in your connect call.
Read http://lists.trolltech.com/qt-interest/2006-01/thread01111-0.html

If that does not help, please post the exact error messages you are getting.

borker
16th April 2009, 18:19
Thanks for the reply and the link. I'll have a more thorough go through tonight when I get home from work and also post the exact code and message and maybe build a simple test case app if the problem is still happening.

My first thought though is that how can I supply a namespace in a base class that won't know what namespace any future subclasses are in. In my example above, how could the connect in the base class in namespace A know what namespace the derived class in namespace B has?

thanks
N

borker
17th April 2009, 01:37
hmmm.... I'm making things worse it seems :confused:

I have 4 files for a test app:

sender.h:


#include <QApplication>

class Sender : public QObject {
public :
Sender(QObject *parent =0) : QObject(parent) {}

void pokeMe() {emit sendData();}

signals :
void sendData() {}
};


genericservice.h


#ifndef GS_H
#define GS_H

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

namespace A {
class GenericService : public QObject {
public :
GenericService(QObject *parent=0);

void sendQuery();

protected slots:
void receiveData();

private :
Sender *m_sender;
};
}

#endif


genericservice.cpp


#include "genericservice.h"

using namespace A;

GenericService::GenericService (QObject *parent) : QObject(parent)
{
m_sender = new Sender(this);
}

void GenericService::sendQuery()
{
connect(m_sender, SIGNAL(sendData()), this, SLOT(receiveData()));
m_sender->pokeMe();
}

void GenericService::receiveData()
{
QDebug(new QString("yo"));
}


and main.cpp


#include <QApplication>

#include "genericservice.cpp"


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

GenericService *gen = new GenericService();
gen->sendQuery();

return app.exec();
}


and now when I build and execute I get:

Object::connect: No such signal QObject::sendData() in genericservice.cpp:13

i.e. the signal from a non-namespaced class is not not being recognized in the namespaced one. I didn't even get around to the derived classes in different namespaces! Could really use some help on this!

faldzip
17th April 2009, 05:32
you forgot the Q_OBJECT macro. It should look like this:


class Sender : public QObject {
Q_OBJECT
public :
Sender(QObject *parent =0) : QObject(parent) {}
/* . . . */
};

without this macro the MOC (Meta Object Compiler) don't make any interest to your class and that's bad, bacause the meta object system is the thing making signal/slots working.

borker
17th April 2009, 13:24
ok, the files above don't work because I'm an idiot ^W^W^W I forgot the Q_OBJECT macro...

borker
17th April 2009, 13:25
you forgot the Q_OBJECT macro. It should look like this:


class Sender : public QObject {
Q_OBJECT
public :
Sender(QObject *parent =0) : QObject(parent) {}
/* . . . */
};

without this macro the MOC (Meta Object Compiler) don't make any interest to your class and that's bad, bacause the meta object system is the thing making signal/slots working.

wow, you posted just before me! just made the change and of course everything went much better... now checking my real code for the same mistake.

cheers
N

borker
17th April 2009, 13:44
Yup... it was a forgotten Q_OBJECT macro. Thanks for the help, I guess I can chalk this one up to experience.

thanks
Nathan