PDA

View Full Version : unable to establish queued connection with QList of own class pointers



Gh0str1d3r
13th July 2010, 18:56
Hi,

I am not able to establish a queued connection of the form


connect(parent(),SIGNAL(signal(QList<const RealDataHandler *>,RealDataHandler *,double)),&calculationClass,SLOT(slot(QList<const RealDataHandler*>,RealDataHandler*,double)));

I always get the following error:


QObject::connect: Cannot queue arguments of type 'QList<const RealDataHandler*>'
(Make sure 'QList<const RealDataHandler*>' is registered using qRegisterMetaType().)

I already registered both, RealDataHandler and QList<const RealDataHandler*> as the very first command of my main.cpp, even tried it with RealDataHandler* allone.


typedef QList<const RealDataHandler*> RealDataHandlerList;
// ....
qRegisterMetaType<RealDataHandler>("RealDataHandler");
qRegisterMetaType<RealDataHandlerList >("RealDataHandlerList");

I really don't understand this. It should not be so difficult to send a list of pointers, should it? Can anyone explain to me what I am doing wrong? Many thanks.

Lykurg
13th July 2010, 18:58
What happens when you use your typedef in the signal?

wysota
13th July 2010, 18:59
Hmm... does having a list of const pointers even work? How do you add items there?

Did you declare a metatype for your class list prior to using qRegisterMetaType?

Gh0str1d3r
13th July 2010, 19:24
what should be the problem with lists of const pointers?

declaring the metatype before registration does not help here.


What happens when you use your typedef in the signal?

This is the solution. Many thanks!

Still I don't understand why I can't use the list directly without defining my own type.

wysota
13th July 2010, 20:08
what should be the problem with lists of const pointers?
How do you assign a value to a const pointer?


Still I don't understand why I can't use the list directly without defining my own type.
Because moc doesn't like templates.

Gh0str1d3r
13th July 2010, 20:35
How do you assign a value to a const pointer?


I don't want to assign anything here, I just want to put the pointers in a list. QList::append(T) does not change T, so T can be const.

wysota
13th July 2010, 21:01
I'm not talking about this particular case here. I mean using such a list is... akward, for example you can't do this:


foreach(const RealDataHandler *ptr, yourList){ // assignment, invalid
doSomething(ptr);
}

You have to do:

for(int i=0;i<yourList.count();++i){
const RealDataHandler *ptr = yourList.at(i); // initialization, not assignment, valid
doSomething(ptr);
}

etc.

As for append() - it works because QList is an advanced class that doesn't preallocate objects in the list, it just preallocates space for them.

By the way, as you are asking for queued connections, I'm assuming you are using threads -- remember you are passing unprotected objects between threads which essentially leads (or may lead) to trouble.

Gh0str1d3r
15th July 2010, 11:50
ok, that's true, didn't think about the foreach loop.

You are right, we are talking about inter-thread communication. What would be the way to protect the object? Transmitting a QMutex with it? Like this


connect(parent(),SIGNAL(signal(QList<const RealDataHandler *>,RealDataHandler *,double,QMutex&)),&calculationClass,SLOT(slot(QList<const RealDataHandler*>,RealDataHandler*,double,QMutex&)));

wysota
15th July 2010, 22:42
Certainly not. The mutex should be part of the object and the list should probably be in a has-a relationship rather than is-a. Better yet, don't pass the list around (it may require the list to be copied!). Let one thread notify the other that something happened so that the other can access the list directly (or something like that).