Qt metaobject system: emit signal using a string with its name

c++, qmetaobject, qt, qt-signals

Solution

Use QMetaObject::invokeMethod

I am using this in my program:

`mCaller` is object with defined slot and `mSlotName` is name of the slot

QMetaObject::invokeMethod(mCaller, mSlotName.toLatin1().constData(), Qt::DirectConnection)

Problem

Qt signal/slot system rocks, but looks that it lacks some really useful functionality (or at least I can't find how to use it). I have a class with lots of signals, and this class has a `switch` which needs to emit a proper signal depending on a variable's value. Now I solve this using C preprocessor: ``` #define CASE(_NAME) \ case MyEnum_ ## _NAME: \ { \ emit MySignal_ ## _NAME(); \ do_other_stuff(); \ break; \ } switch(val) { CASE(Val_1) CASE(Val_2) CASE(Val_3) } ``` This just doesn't look right. I am sure there is a more elegant way. `QMetaObject` has an `indexOfSignal` method which can give me the Qt's internal ID of the signal using a string with its name. If I could emit a signal using this ID, my code would become much cleaner. I've peeked at the signal method implementation generated by `moc`, and it looks like the the only thing that differs from one signal to another is a single digit: ``` void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) }; QMetaObject::activate(this, &staticMetaObject, <signal_id>, _a); ``` where `<signal_id>` is an integer unique for each signal. So, the question is, how do I `emit(int signalIdx)`? Or at least get a chance to call `QMetaObject::activate`, since it looks buried in private headers?

Original source