2013-08-25 37 views
5

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()?

+1

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

+0

@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}' –

+0

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 –

Odpowiedz

1

Teraz moje pytanie brzmi: jak przyszłościowe jest to rozwiązanie, zwłaszcza dlatego, że zakładam, że indeks musi być co najmniej jeden większy niż methodCount()?

Powinno działać już teraz.

Co do przyszłego dowodu ... może być. Fragment używa nieobsługiwanych funkcji, co oznacza, że ​​mogą się one złamać w dowolnym momencie w przyszłości. Prawdopodobnie będzie nadal działać.