Mechanizm sygnalizacji/szczeliny w Qt to mechanizm statyczny. Klasy muszą być wstępnie przetworzone przez kompilator moc.
Teraz chcę tworzyć sygnały i gniazda dynamicznie w czasie wykonywania.
Mam już działające rozwiązanie, ale wydaje mi się, że jestem hackem, chociaż używam publicznie dostępnych metod.
Jest to kod dla dynamicznych gniazd:Jak tworzyć dynamiczne sygnały i gniazda w Qt?
bool DynamicQObject::connectDynamicSlot(const QString &objectName, QObject *pSourceObject, QMetaMethod signalMethod)
{
QByteArray slotName = signalMethod.name().prepend("on").append("(");
QStringList parameters;
for (int i = 0, j = signalMethod.parameterCount(); i < j; ++i)
{
parameters << QMetaType::typeName(signalMethod.parameterType(i));
}
slotName.append(parameters.join(",")).append(")");
QByteArray theSignal = QMetaObject::normalizedSignature(signalMethod.methodSignature().constData());
QByteArray theSlot = QMetaObject::normalizedSignature(slotName);
if (!QMetaObject::checkConnectArgs(theSignal, theSlot))
{
return false;
}
int signalId = pSourceObject->metaObject()->indexOfSignal(theSignal);
if (signalId < 0)
{
return false;
}
int slotId = slotIndices.value(theSlot, -1);
if (slotId < 0)
{
slotId = slotList.size();
slotIndices[theSlot] = slotId;
slotList.append(createSlot(theSlot, objectName, signalMethod));
}
return QMetaObject::connect(pSourceObject, signalId, this, slotId + metaObject()->methodCount());
}
Jak widać, robię intensywne wykorzystanie QMetaObject, a szczególnie indeks szczelin (liczba metoda).
Kod dla sygnałów dynamicznych jest porównywalny.
Teraz moje pytanie brzmi: w jaki sposób jest to rozwiązanie przyszłościowe, szczególnie dlatego, że zakładam, że indeks musi być co najmniej jeden większy od metody methodCount()?
Myślę, że gdybyś wyjaśnił konkretny scenariusz, w którym jest to dla ciebie użyteczne, ludzie mogą dać ci lepsze alternatywy, niż to, aby je wdrożyć. – Mat
@Mat Masz rację, ale chcę tylko wiedzieć, czy ta implementacja ma charakter przyszłościowy. Odnośnie scenariusza: Pracuję nad platformą pubsub, w której zdarzenia mogą być dynamicznie integrowane. Powyższy kod jest, a.o. używany w kliencie C++ socket.io. Dzięki tej implementacji możliwe jest wykonanie następujących czynności: 'socketIoObject.connect (" customEvent ", & socketIoObject, [=] (Event e) {event procesu}' –
Powinieneś udostępnić architekturę.Niektórym opis byłby lepszy niż kod. wszystko, co widzę, to to, że łączysz się z nieistniejącym slotem, który istnieje tylko na twojej własnej liście w ramach 'DynamicQObject' Co ważne jest to, jak integrujesz to z maszyną metacall, łącząc wydarzenia z lambdą lub emisją zdarzeń. zrobione bez potrzeby dynamicznych sygnałów/slotów Nic nie zyskujesz przez przeorganizowanie 'QObject :: connect' Powinieneś po prostu stworzyć własną metodę do tego, IMHO –