Question

I have something like this:

class Thing : public QObject {
  ...
  public slots:
    void doSomething ();
  ...
};

I then have an object that manages Things, like this:

class ManyThings : public QObject { 
  ...
  public: 
    void makeThingDoSomething (int thingIndex);
  private:
    QVector<Thing *> things_;
  ...
};

My question is this: The Things in ManyThing's collection are scattered among a few different threads. I'd like makeThingDoSomething(int) to call the things_[thingIndex]->doSomething() slot as if the slot was called from a signal connected with Qt::AutoConnection. Essentially this, but using Qt's queuing mechanism if the Thing is on a different thread than the caller:

void ManyThings::makeThingDoSomething (int thingIndex) {
  // i want to do this AutoConnection style, not direct:
  things_[thingIndex]->doSomething();
  // doesn't *need* to block for completion
}

What's the simplest way to set this up? I could make a signal in ManyThings and connect it to each of the Thing's slots, but then emitting that signal would call the slot on every Thing, not just a specific one. Is there some way to easily set up connections so that I can connect the same signal to different object's slots depending on an index parameter passed to the signal, or something? Or some way to call the slot using Qt's signal/slot mechanism without actually having to create a signal?

Was it helpful?

Solution

Try using QMetaObject::invokeMethod:

void ManyThings::makeThingDoSomething(int thingIndex) {
   QMetaObject::invokeMethod(things_[thingIndex], "doSomething", 
                             Qt::AutoConnection);
}

Note that doSomething will likely have to remain a slot if you use this approach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top