рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ Qt рдореЗрдЯрд╛ рд╕рд┐рд╕реНрдЯрдоред рднрд╛рдЧ 2 - рд╕рд┐рдЧреНрдирд▓ рдФрд░ рд╕реНрд▓реЙрдЯ


рднрд╛рдЧ 1 - рдЧреБрдг
рд╣рдо рдХреНрдпреВрдЯреА рдореЗрдЯрд╛рд╕рд┐рд╕реНрдЯрдо рд╕реЗ рдирд┐рдкрдЯрдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВред рдЗрд╕ рдмрд╛рд░, рд╡рд░реНрдЪреБрдЕрд▓ рд╕рд┐рдЧреНрдирд▓ рдФрд░ рд╕реНрд▓реЙрдЯ рдмрдирд╛рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

1. рд╕рдВрдХреЗрдд


рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдХрд┐рд╕реА рднреА рд╕рд┐рдЧреНрдирд▓ рд╕реЗ рдХрдиреЗрдХреНрд╢рдиред рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдХреЗрд╡рд▓ рддрд░реНрдХ 0 рд╕реЗ 10 рддрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд▓рдХреНрд╖реНрдп рдПрдХ рдбрд╛рдпрдиреЗрдорд┐рдХрдСрдмрдЬреЗрдХреНрдЯ рдХреНрд▓рд╛рд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рд╕рд┐рдЧреНрдирд▓ рд╕реЗ рдХрдиреЗрдХреНрдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕рдХреНрд░рд┐рдп рд╣реЛрдиреЗ рдкрд░ рд╕рд┐рдЧреНрдирд▓ рдирд╛рдо рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ QVariantList рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рддрд░реНрдХред рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рдХреЛ рднреА рддреЛрдбрд╝ рджреВрдВрдЧрд╛, рдЪрд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ:
dynamicqobject.h
class DynamicQObject : public QObject { public: DynamicQObject(QObject *mapToObject, const char *signalCatchMethod, QObject *parent = 0); bool addSlot(QObject *object, const char *signal, const QString &slotName); bool removeSlot(const QString &name); bool addSignal(const QString &name, QObject *object, const char *slot); bool removeSignal(const QString &name); bool activate(const QString &signalName, const QVariantList &args); int qt_metacall(QMetaObject::Call call, int id, void **arguments); private: // virtual slots bool containsSlot(const QString &name); QObject *m_mapTo; const char *m_catchMethod; typedef struct { bool isEmpty; // true after removeSlot() QObject *object; int signalIdx; QString name; // virtual slot name QVector<int> parameterTypes; } slot_t; QVector<slot_t> m_slotList; // virtual signals typedef struct { bool isEmpty; // // true after removeSignal() QObject *reciever; int slotIdx; QString name; QVector<int> parameterTypes; } signal_t; QVector<signal_t> m_signalList; QHash<QString, int> m_signalHash; void *m_parameters[11]; // max 10 parameters + ret value }; 


addSlot - рдПрдХ рдирдпрд╛ рд╡рд░реНрдЪреБрдЕрд▓ рд╕реНрд▓реЙрдЯ рдмрдирд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рд╕реНрд▓реЙрдЯрдирд╛рдо рд╣реИ рдФрд░ рдЗрд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд┐рдЧреНрдирд▓ рд╕рд┐рдЧреНрдирд▓ рд╕реЗ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
 bool DynamicQObject::addSlot(QObject *object, const char *signal, const QString &slotName) { if (containsSlot(slotName)) return false; if (signal[0] != '2') { qWarning() << "Use SIGNAL() macro"; return false; } 

рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╣реА рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрд▓реЙрдЯ рд╣реИ, рд╕рд╛рде рд╣реА рдЙрд╕рдХреЗ рдирд╛рдо рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЪрд░рд┐рддреНрд░ '2' рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реИ, рдпрд╣ рдкреНрд░рддреАрдХ SIGNAL () рдореИрдХреНрд░реЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
  QByteArray theSignal = QMetaObject::normalizedSignature(&signal[1]); int signalId = object->metaObject()->indexOfSignal(theSignal); if (signalId < 0) { qWarning() << "signal" << signal << "doesn't exist"; return false; } QVector<int> parameterTypes; QMetaMethod signalMethod = object->metaObject()->method(signalId); for (int i = 0; i < signalMethod.parameterCount(); ++i) parameterTypes.push_back(signalMethod.parameterType(i)); 

рдкрд┐рдЫрд▓реА рдмрд╛рд░ рдХреЗ рд╕рд╛рде-рд╕рд╛рде, рд╣рдореЗрдВ рд╕рд┐рдЧреНрдирд▓ рдЗрдВрдбреЗрдХреНрд╕ рдорд┐рд▓рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╣рдореЗрдВ рдЗрд╕ рдЗрдВрдбреЗрдХреНрд╕ рдкрд░ QMetaMethod рдорд┐рд▓рддрд╛ рд╣реИред рдЬрд┐рд╕рд╕реЗ рд╣рдореЗрдВ рдПрдХ рд╕рдордп рдореЗрдВ рд╕рдВрдХреЗрдд рддрд░реНрдХ рдорд┐рд▓рддреЗ рд╣реИрдВ, рдЙрдирд╕реЗ рдПрдХ рд╡реЗрдХреНрдЯрд░ рдмрдирд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЗрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдкреНрдд рддрд░реНрдХреЛрдВ рдХреЛ рдХрдо рдХрд░реЗрдВрдЧреЗред
  int slotIdx = -1; for (int i = 0; i < m_slotList.count(); ++i) { if (m_slotList[i].isEmpty == true) { slotIdx = i; break; } } bool addEntry = false; if (slotIdx == -1) { addEntry = true; slotIdx = m_slotList.count(); } 

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рд╣рдо m_slotList рдореЗрдВ рдПрдХ рдЦрд╛рд▓реА рд░рд┐рдХреЙрд░реНрдб (рдпрд╛ рдПрдХ рдирдпрд╛ рдмрдирд╛рдПрдВ) рдкрд╛рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рд╣рдо рдмрдирд╛рдП рдЧрдП рд╕реНрд▓реЙрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рд╣реЗрдЬреЗрдВрдЧреЗред рдЦрд╛рд▓реА рд░рд┐рдХреЙрд░реНрдбреНрд╕ рд╕реНрд▓реЙрдЯреНрд╕ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рдж рдмрдирддреЗ рд╣реИрдВ (removeSlot ()), рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рд╕реВрдЪрдХрд╛рдВрдХ рд╕реНрд▓реЙрдЯреНрд╕ рд╕реЗ рдмрдВрдзреЗ рд╣реИрдВ, рдЙрдирдХреА рд╢рд┐рдлреНрдЯ рдореЗрдВ рдЕрдорд╛рдиреНрдп рд╕реНрд▓реЙрдЯреНрд╕ рдХрд╛ рдХреЙрд▓ рдЖрдПрдЧрд╛ред рдпрд╣рд╛рдВ QHash рдпрд╛ QMap рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рд╡реЗ рд╕реНрд▓реЙрдЯреНрд╕ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдХрдо рдмрд╛рд░ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдмрд╣реБрдд рдмрд╛рд░ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╡реЗрдХреНрдЯрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреА рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдкрд╣реБрдВрдЪ O (1) рдХреЗ рд▓рд┐рдП рд╣реИ, рдФрд░ QMap рдФрд░ QHash рдХреЗ рд▓рд┐рдП, рдХреНрд░рдорд╢рдГ, O (logn) рдФрд░ O (n) рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдХреЗрд╡рд▓ рд╕рд┐рдЧреНрдирд▓ рд╕реЗ рдЬреБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реА рд░рд╣рддрд╛ рд╣реИ:
  if (!QMetaObject::connect(object, signalId, this, slotIdx + metaObject()->methodCount())) { qWarning() << "can't connect" << signal << "signal to virtual slot"; return false; } if (addEntry) { m_slotList.push_back({false, object, signalId, slotName, parameterTypes}); } else { slot_t &slot = m_slotList[slotIdx]; slot.isEmpty = false; slot.object = object; slot.signalIdx = signalId; slot.name = slotName; slot.parameterTypes = parameterTypes; } return true; } 

рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдмрдЪрд╛рдПрдВред

рд╕реНрд▓реЙрдЯ рдХреЙрд▓

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлреЛрдХрд╕ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ, рд╣рдо qt_metacall рдХрд╛ рдЕрдкрдирд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛рддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдзрд┐рдХ рддрд░реНрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
 int DynamicQObject::qt_metacall(QMetaObject::Call call, int id, void **arguments) { id = QObject::qt_metacall(call, id, arguments); if (id < 0 || call != QMetaObject::InvokeMetaMethod) return id; Q_ASSERT(id < m_slotList.size()); 

рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрд▓реЙрдЯ (рдореЗрдЯрд╛рдореЗрдереЛрдб) рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рднреА рдХрд┐ рд╕реВрдЪрдХрд╛рдВрдХ рд╕рд╣реА рд╣реИред
  const slot_t &slotInfo = m_slotList[id]; QVariantList parameters; for (int i = 0; i < slotInfo.parameterTypes.count(); ++i) { void *parameter = arguments[i + 1]; parameters.append(QVariant(slotInfo.parameterTypes[i], parameter)); } 

рд╣рдо рд╕реНрд▓реЙрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╕рд╣реЗрдЬреА рдЧрдИ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдлрд┐рд░ рд╣рдо рдкреНрд░рд╛рдкреНрдд рддрд░реНрдХреЛрдВ рдФрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ QVariants рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рддреЗ рд╣реИрдВред
  QMetaObject::invokeMethod(m_mapTo, m_catchMethod, Q_ARG(QString, slotInfo.name), Q_ARG(QVariantList, parameters)); return -1; } 

рдпрд╣ рдХреЗрд╡рд▓ рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ рд╕реНрд▓реЙрдЯ, рдФрд░ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред

рд╣рдЯрд╛рдиреЗ рдореЗрдВ рдХреБрдЫ рднреА рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИ (), рддреЛ рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рддреБрд░рдВрдд рдирдЬрд╝рд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ:
 Reciever reciever; DynamicQObject dynamic(&reciever, "signalCatched"); Tester tester; dynamic.addSlot(&tester, SIGNAL(signal1(int,int,QString)), "myslot1"); dynamic.addSlot(&tester, SIGNAL(signal2(QPoint)), "myslot2"); tester.emitSignal1(); tester.emitSingal2(); 

рдбрд╛рдпрдиреЗрдорд┐рдХрдСрдмреНрдЬреЗрдХреНрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ, рд╣рдо рдХрд┐рд╕реА рднреА QObject рд╡рдВрд╢рдЬ рдФрд░ рд╡рд┐рдзрд┐ рдирд╛рдо (Q_INVOKABLE) рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐рд╕реА рднреА рд╕рд┐рдЧреНрдирд▓ рдХреЛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдореЗрдВ рдирд┐рдореНрди рд╡рд┐рдзрд┐ рд╣реИ: Q_INVOKABLE рд╢реВрдиреНрдп рд╕рд┐рдЧреНрдирд▓рдХреИрдЪ (const QString & signalName, const QVariantList & args) , рдЬреЛ рдХреЗрд╡рд▓ рдХрдВрд╕реЛрд▓ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рддрд░реНрдХ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдФрд░ рдкрд░реАрдХреНрд╖рдХ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рджреЛ рд╕рдВрдХреЗрдд рд╣реИрдВ, рдФрд░ рджреЛ рдХрд╛рд░реНрдп рдЬреЛ рдЙрдиреНрд╣реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдо рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ:
"рдореИрд╕реВрд░рд▓ 1" (QVariant (int, 123), QVariant (int, 456), QVariant (QString, "str"))
рдореИрд╕реВрд░рд▓ 2 (QVariant (QPoint, QPoint (3,4)))

рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ :) рдЖрдк рдХреНрдпреВрдЯреА рдореЗрдЯрд╛рд╕рд┐рд╕реНрдЯреНрдо рдХреЗ рд▓рд┐рдП рдЬреНрдЮрд╛рдд рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

2. рд╕реНрд▓реЙрдЯ


рдпрд╛рдиреА рд╡рд░реНрдЪреБрдЕрд▓ рд╕рд┐рдЧреНрдирд▓ рдмрдирд╛рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдзрд╛рд░рдг рд╕реНрд▓реЙрдЯреНрд╕ рд╕реЗ рдЬреЛрдбрд╝рдирд╛, рдПрдХ рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рднреНрд░рдорд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ ... рдЗрд╕рдХреЗ рд▓рд┐рдП 3 рдлрд╝рдВрдХреНрд╢рди рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ: addSignal (), removeSignal () рдФрд░ рдПрдХреНрдЯрд┐рд╡реЗрдЯ ()ред
рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рд╕рд┐рдЧреНрдирд▓ рдирд┐рд░реНрдорд╛рдг:
 bool DynamicQObject::addSignal(const QString &name, QObject *object, const char *slot) { if (slot[0] != '1') { qWarning() << "Use SLOT() macro"; return false; } int slotIdx = object->metaObject()-> indexOfSlot(&slot[1]); // without 1 added by SLOT() macro if (slotIdx < 0) { qWarning() << slot << "slot didn't exist"; return false; } 

рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╣рдо рдЬрд╛рдБрдЪрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рд╡реИрд╕рд╛ рд╣реА рдЪрд▓ рд░рд╣рд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдЙрд╕реЗ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  QVector<int> parameterTypes; QMetaMethod slotMethod = object->metaObject()->method(slotIdx); for (int i = 0; i < slotMethod.parameterCount(); ++i) parameterTypes.push_back(slotMethod.parameterType(i)); int signalIdx = -1; for (int i = 0; i < m_slotList.count(); ++i) { if (m_slotList[i].isEmpty == true) { signalIdx = i; break; } } bool addEntry = false; if (signalIdx == -1) { addEntry = true; signalIdx = m_signalList.count(); } 

рдЗрд╕реА рдкреНрд░рдХрд╛рд░, рд╣рдо рддрд░реНрдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╡реЗрдХреНрдЯрд░ рдмрдирд╛рддреЗ рд╣реИрдВред
  if (!QMetaObject::connect(this, signalIdx + metaObject()->methodCount(), object, slotIdx)) { qWarning() << "can't connect virtual signal" << name << "to slot" << slot; return false; } if (addEntry) { m_signalList.append({false, object, slotIdx, name, parameterTypes}); } else { signal_t &signal = m_signalList[signalIdx]; signal.isEmpty = false; signal.reciever = object; signal.slotIdx = slotIdx; signal.name = name; signal.parameterTypes = parameterTypes; } m_signalHash.insert(name, signalIdx); return true; } 

рдФрд░ рдлрд┐рд░, рд╕рдм рдХреБрдЫ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИ - рд╣рдо рдЕрдкрдиреЗ рд╡рд░реНрдЪреБрдЕрд▓ рд╕рд┐рдЧреНрдирд▓ рдХреЛ рд╕реНрд▓реЙрдЯ рд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдФрд░ m_signalHash рдореЗрдВ рдПрдХ рдЬреЛрдбрд╝реА рдирд╛рдо - рд╕рд┐рдЧреНрдирд▓ рдЗрдВрдбреЗрдХреНрд╕ рднреА рд╕реЗрд╡ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрдм рд╕рдВрдХреЗрдд рд╕рдХреНрд░рд┐рдп рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдирд╛рдо рд╕реЗ рдЗрд╕рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо рд╣рдЯрд╛рдиреЗ, рдпрд╛ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ ...

рд╕рдВрдХреЗрдд рд╕рдХреНрд░рд┐рдпрдг

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирдП рдмрд┐рдВрджреБ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрд╛рд╕реНрдЯрд┐рдВрдЧред
 bool DynamicQObject::activate(const QString &signalName, const QVariantList &args) { int signalIdx = m_signalHash.value(signalName, -1); if (signalIdx == -1) { qWarning() << "signal" << signalName << "doesn't exist"; return false; } signal_t &signal = m_signalList[signalIdx]; 

рд╣рдо рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрдХреЗрдд рдореМрдЬреВрдж рд╣реИ рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдЬрд╛рдирдХрд╛рд░реА рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред
  if (args.count() < signal.parameterTypes.count()) { qWarning() << "parameters count mismatch:" << signalName << "provided:" << args.count() << "need >=:" << signal.parameterTypes.count(); return false; } 

рд╣рдо рдЬрд╛рдБрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реНрдпрд╛рдкреНрдд рддрд░реНрдХ рд╣реИрдВ, рд╣рдо рдХреЗрд╡рд▓ рдЕрддрд┐рд╢рдпреЛрдХреНрддрд┐ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ ...
  QVariantList argsCopy = args; for (int i = 0; i < signal.parameterTypes.count(); ++i) { if (!argsCopy[i].convert(signal.parameterTypes[i])) { qWarning() << "can't cast parameter" << i << signalName; return false; } m_parameters[i + 1] = argsCopy[i].data(); } 

рддрд░реНрдХ рд╕реВрдЪреА рдХреА рдПрдХ рдкреНрд░рддрд┐ рдмрдирд╛рдПрдБ, рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╕реНрдерд┐рд░ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдЗрд╕реЗ рдмрджрд▓реЛред рдФрд░ рдлрд┐рд░ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рддрд░реНрдХ рдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рддреЛ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрд▓реЙрдЯ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ, рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдХреНрд░рд┐рдп рддрд░реНрдХ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реБрдП, QString, рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИред
рдПрдХ рдЙрджрд╛рд╣рд░рдг:
  DynamicQObject dynamic(&reciever, "signalCatched"); Reciever reciever; dynamic.addSignal("virtual_signal", &reciever, SLOT(slot1(int,QString))); dynamic.activate("virtual_signal", QVariantList() << "123" << QString("qwerty") << 2 << 3); 

рддрджрдиреБрд╕рд╛рд░, Reciever рдореЗрдВ рдПрдХ рдирд┐рдпрдорд┐рдд рд╕реНрд▓реЙрдЯ рд╣реЛрддрд╛ рд╣реИред рд╣рдо рдПрдХ рдЖрднрд╛рд╕реА рд╕рдВрдХреЗрдд рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рддрд░реНрдХреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдХрд╣рддреЗ рд╣реИрдВред
рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:
slot1_call 123 "рдорд╛рддреНрд░рд╛"

рджреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ рдЫреЛрдбрд╝ рджрд┐рдП рдЧрдП рдереЗ, рдФрд░ рдкрд╣рд▓реА рдмрд╛рд░, рдЯрд╛рдЗрдк рд░реВрдкрд╛рдВрддрд░рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рдЖрд╡рд╢реНрдпрдХ рдЪреАрдЬ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдпрд╣ рдЕрдкрдиреЗ рдЖрдк рдирд┐рдХрд▓рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЖрдк рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ...

рдЕрднреА рдХреЗ рд▓рд┐рдП рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдЕрдЧрд▓рд╛, рд╣рдо рддрд░реАрдХреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗ, рдФрд░ рдПрдХ рд╕рд░рд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рддреЗрдЬ рдХрд░реЗрдВрдЧреЗ ...

PS рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рд▓рд┐рдЦрдиреЗ рдореЗрдВ, рд▓реЗрдЦ: рдбрд╛рдпрдирд╛рдорд┐рдХ рд╕рд┐рдЧреНрдирд▓ рдФрд░ рд╕реНрд▓реЙрдЯ , рдЬрд┐рдирд╕реЗ рдЖрдк рдмрд╣реБрдд рд╕рд╛рд░реА рджрд┐рд▓рдЪрд╕реНрдк рдЪреАрдЬреЗрдВ рд╕реАрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорджрдж рдХреАред

Source: https://habr.com/ru/post/In198780/


All Articles