PDA

View Full Version : One signal more slots



paolom
30th July 2012, 17:23
Hi,
I've a manager who handles more objects, each of them lives in a different thread.
During the creation of this objects, I connect a signal of a manager to a slot of the objects.

My goal is to emit a signal from manager and execute only one object slot.

I think I can enumerate all the objects and then invoke a signal with a parameters than identify the number of the object.
So every object receive the signal but when compare the signal parameter, only one object execute the slot.

I think this is a simple solution, but I don't think it's the best, in particular If I've a large number of objects.

Do you have any solutions?

Thanks

amleto
30th July 2012, 17:46
You can just keep a pointer of all objects in the manager and use a QHash using the id parameters to make a key




struct Object
{
void bar(){/* do nothing */}
};

class Manager
{
QHash<Key, Object*> map;

void foo()
{
// do something with 'key's object:
Key key;
map[key]->bar(); // no need to run method for each key/object
}
};

paolom
31st July 2012, 09:33
I can't do this cause the object lives in different threads.

I've something like this:



class Manager : public QObject
{
Q_OBJECT

signals:
void invokeObjMethod(int);

private:
void initManager(){

for ( int idx = 0 ; idx < n; idx++){
QThread * th = new QThread(this);
MyObject * obj = new MyObject(idx);
connect(this,SIGNAL(invokeObjMethod(int)),obj,SLOT (doSomething(int)));
obj->moveToThread(th);
th->start();
}
}
}

class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(int idx, QObject * parent = 0)
:QObject(parent),
m_index(idx){}

private:
int m_index;

public slots:
void doSomething(int idx){
if ( idx != m_index)
return;

...do Something ...
}
}



When the manager emit the signal invokeObjMethod(int) all the objects invoke their slot but only one do something.
I want to know if this is the right way or there are other best solu

spirit
31st July 2012, 09:41
QSignalMapper?

paolom
31st July 2012, 09:49
The QSignalMapper class bundles signals from identifiable senders.
In my case I've only one sender.
I think that is not possible to use QSignalMapper in my case.

Am I wrong?

yeye_olive
31st July 2012, 10:39
You are right. QSignalMapper cannot help you here.

There is a simple solution to your problem: QMetaObject::invokeMethod(). No more indices, just do something like

QMetaObject::invokeMethod(pointerToTheMyObjectInst ance, "doSomething", Qt::QueuedConnection);

paolom
31st July 2012, 11:01
With this method I can directly call the thread slot of the single object, with QueuedConnection (safety for thread).

I think it's the best solution....many thanks!!!

amleto
31st July 2012, 11:48
I can't do this cause the object lives in different threads.

Yes you can, just use invokeMethod and use it with a queued connection slot.