KShots
16th May 2007, 20:14
EDIT: Sorry about the mess, I was hoping the code scrollbar would keep things neater than this...
Hello all,
I'm attempting to use QMetaObject to utilize reflection concepts to connect signals in one plugin system to slots in another plugin system that match naming conventions. The basic idea is that if an input plugin has a signal like mySignal*SIGNAL_NAME*(*ARGS*), then a slot in another plugin may or may not have a slot that matches, like so: mySlot*SLOT_NAME*(*ARGS*).
I've found that during run-time, QMetaObject Qt plugins do indeed find signals and slots that are not defined in the interface (which is exactly what I was looking for)... but to make the connections, I find that I'm getting warnings on the console that say the following:
Object::connect: Use the SIGNAL macro to bind evilcpcInputVoiceSignals::evilcpcSignalActivateDVD ()
I'm using the following to make the connection:
. foreach(evilcpcInput * i, lPluginInput)
{ //For all input plugins
evilcpcInputSignals * si = i->getSignals();
const QMetaObject * imo = si->metaObject();
foreach(mi, lPluginMenuItems)
{ //For all menu item plugins
evilcpcMenuItemSlots * sl = mi->getSlots();
const QMetaObject * mimo = sl->metaObject();
for(int index(0); index < imo->methodCount(); index++)
{ //for all methods of the current input plugin
if(imo->method(index).methodType() == QMetaMethod::Signal)
{ //if this method is a signal
QString signalSignature = imo->method(index).signature();
if(signalSignature.startsWith("evilcpcSignal", Qt::CaseSensitive))
{ //It's a legitimate signature
QString signalName = signalSignature;
signalName.remove(0, strlen("evilcpcSignal"));
int position(signalName.indexOf('('));
signalName.remove(position, signalName.length() - position);
for(int index1(0); index1 < mimo->methodCount(); index1++)
{ //for all methods of the current menu item plugin
if(mimo->method(index1).methodType() == QMetaMethod::Slot)
{ //if this method is a slot
QString slotSignature = mimo->method(index1).signature();
if(slotSignature.startsWith("evilcpcSlot", Qt::CaseSensitive))
{ //It's a legitimate slot
QString slotName = slotSignature;
slotName.remove(0, strlen("evilcpcSlot"));
position = slotName.indexOf('(');
slotName.remove(position, slotName.length() - position);
if(signalName == slotName && imo->method(index).parameterTypes() == mimo->method(index1).parameterTypes())
{ //Signal matches slot, so connect them
QObject::connect(si, signalSignature.toAscii().data(), sl, slotSignature.toAscii().data());
std::cerr << "input plugin '" << i->getName().toAscii().data() << "' signal '" << signalSignature.toAscii().data() << "' connected to menu item plugin '" << mi->getName().toAscii().data() << "' slot '" << slotSignature.toAscii().data() << '\'' << std::endl;
}
}
}
}
}
}
}
}
}All my signatures look about right. How exactly should I be using connect, then?
Hello all,
I'm attempting to use QMetaObject to utilize reflection concepts to connect signals in one plugin system to slots in another plugin system that match naming conventions. The basic idea is that if an input plugin has a signal like mySignal*SIGNAL_NAME*(*ARGS*), then a slot in another plugin may or may not have a slot that matches, like so: mySlot*SLOT_NAME*(*ARGS*).
I've found that during run-time, QMetaObject Qt plugins do indeed find signals and slots that are not defined in the interface (which is exactly what I was looking for)... but to make the connections, I find that I'm getting warnings on the console that say the following:
Object::connect: Use the SIGNAL macro to bind evilcpcInputVoiceSignals::evilcpcSignalActivateDVD ()
I'm using the following to make the connection:
. foreach(evilcpcInput * i, lPluginInput)
{ //For all input plugins
evilcpcInputSignals * si = i->getSignals();
const QMetaObject * imo = si->metaObject();
foreach(mi, lPluginMenuItems)
{ //For all menu item plugins
evilcpcMenuItemSlots * sl = mi->getSlots();
const QMetaObject * mimo = sl->metaObject();
for(int index(0); index < imo->methodCount(); index++)
{ //for all methods of the current input plugin
if(imo->method(index).methodType() == QMetaMethod::Signal)
{ //if this method is a signal
QString signalSignature = imo->method(index).signature();
if(signalSignature.startsWith("evilcpcSignal", Qt::CaseSensitive))
{ //It's a legitimate signature
QString signalName = signalSignature;
signalName.remove(0, strlen("evilcpcSignal"));
int position(signalName.indexOf('('));
signalName.remove(position, signalName.length() - position);
for(int index1(0); index1 < mimo->methodCount(); index1++)
{ //for all methods of the current menu item plugin
if(mimo->method(index1).methodType() == QMetaMethod::Slot)
{ //if this method is a slot
QString slotSignature = mimo->method(index1).signature();
if(slotSignature.startsWith("evilcpcSlot", Qt::CaseSensitive))
{ //It's a legitimate slot
QString slotName = slotSignature;
slotName.remove(0, strlen("evilcpcSlot"));
position = slotName.indexOf('(');
slotName.remove(position, slotName.length() - position);
if(signalName == slotName && imo->method(index).parameterTypes() == mimo->method(index1).parameterTypes())
{ //Signal matches slot, so connect them
QObject::connect(si, signalSignature.toAscii().data(), sl, slotSignature.toAscii().data());
std::cerr << "input plugin '" << i->getName().toAscii().data() << "' signal '" << signalSignature.toAscii().data() << "' connected to menu item plugin '" << mi->getName().toAscii().data() << "' slot '" << slotSignature.toAscii().data() << '\'' << std::endl;
}
}
}
}
}
}
}
}
}All my signatures look about right. How exactly should I be using connect, then?