Results 1 to 9 of 9

Thread: reflection and qmetaobject

  1. #1
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default reflection and qmetaobject

    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:
    Qt Code:
    1. Object::connect: Use the SIGNAL macro to bind evilcpcInputVoiceSignals::evilcpcSignalActivateDVD()
    To copy to clipboard, switch view to plain text mode 

    I'm using the following to make the connection:
    Qt Code:
    1. . foreach(evilcpcInput * i, lPluginInput)
    2. { //For all input plugins
    3. evilcpcInputSignals * si = i->getSignals();
    4. const QMetaObject * imo = si->metaObject();
    5. foreach(mi, lPluginMenuItems)
    6. { //For all menu item plugins
    7. evilcpcMenuItemSlots * sl = mi->getSlots();
    8. const QMetaObject * mimo = sl->metaObject();
    9. for(int index(0); index < imo->methodCount(); index++)
    10. { //for all methods of the current input plugin
    11. if(imo->method(index).methodType() == QMetaMethod::Signal)
    12. { //if this method is a signal
    13. QString signalSignature = imo->method(index).signature();
    14. if(signalSignature.startsWith("evilcpcSignal", Qt::CaseSensitive))
    15. { //It's a legitimate signature
    16. QString signalName = signalSignature;
    17. signalName.remove(0, strlen("evilcpcSignal"));
    18. int position(signalName.indexOf('('));
    19. signalName.remove(position, signalName.length() - position);
    20. for(int index1(0); index1 < mimo->methodCount(); index1++)
    21. { //for all methods of the current menu item plugin
    22. if(mimo->method(index1).methodType() == QMetaMethod::Slot)
    23. { //if this method is a slot
    24. QString slotSignature = mimo->method(index1).signature();
    25. if(slotSignature.startsWith("evilcpcSlot", Qt::CaseSensitive))
    26. { //It's a legitimate slot
    27. QString slotName = slotSignature;
    28. slotName.remove(0, strlen("evilcpcSlot"));
    29. position = slotName.indexOf('(');
    30. slotName.remove(position, slotName.length() - position);
    31. if(signalName == slotName && imo->method(index).parameterTypes() == mimo->method(index1).parameterTypes())
    32. { //Signal matches slot, so connect them
    33. QObject::connect(si, signalSignature.toAscii().data(), sl, slotSignature.toAscii().data());
    34. 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;
    35. }
    36. }
    37. }
    38. }
    39. }
    40. }
    41. }
    42. }
    43. }
    To copy to clipboard, switch view to plain text mode 
    All my signatures look about right. How exactly should I be using connect, then?
    Life without passion is death in disguise

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reflection and qmetaobject

    Qt Code:
    1. QObject::connect(si, signalSignature.toAscii().data(), sl, slotSignature.toAscii().data());
    To copy to clipboard, switch view to plain text mode 
    SIGNAL and SLOT macros take a const char * as a parameter.
    Therefore use:
    Qt Code:
    1. QObject::connect(si, SIGNAL(signalSignature.toAscii().constData() ), sl, SLOT(slotSignature.toAscii().constData()) );
    To copy to clipboard, switch view to plain text mode 
    Please note constData() above, and not data().

    Regards

  3. #3
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: reflection and qmetaobject

    If I use the SIGNAL and SLOT macros, this will not work.

    I am passing a variable representing a signal / slot, rather than the signal / slot itself. Using the SIGNAL and SLOT method gives me console errors saying that signalSignature.toAscii().data() does not exist, and signalSignature.toAscii().data() does not exist.

    Of course they do not exist, they are the variables, not the actual signal and slot names
    Life without passion is death in disguise

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reflection and qmetaobject

    Could you post a sample console output when using SIGNAL and SLOT?
    Also, use signalSignature.toAscii().constData(), instead of data.

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reflection and qmetaobject

    Anyway, signalSignature.toAscii().constData() will evaluate to a (const char*) at runtime, so I believe you should not get that message.

  6. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: reflection and qmetaobject

    Actually, forget what I said before...
    connect expects a const char*, not SIGNAL and SLOT, so use constData instead and it will most likely work!

    Regards

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: reflection and qmetaobject

    SIGNAL and SLOT macros are a little hack Use this instead:
    Qt Code:
    1. QObject::connect(si, (QString("2")+signalSignature).toAscii().data(),
    2. sl, (QString("1")+slotSignature).toAscii().data());
    To copy to clipboard, switch view to plain text mode 

  8. The following user says thank you to wysota for this useful post:

    KShots (16th May 2007)

  9. #8
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: reflection and qmetaobject

    Switched over to constData() for the QString signature conversions. I'm still getting the same problem. I've modified my connect slightly so I can check for a successful connection, and I get the following in the console now:

    Qt Code:
    1. Object::connect: Use the SIGNAL macro to bind evilcpcInputVoiceSignals::evilcpcSignalActivateDVD()
    2. Failed to connect input plugin'Voice' signal 'evilcpcSignalActivateDVD()' to menu item plugin 'DVD' slot 'evilcpcSlotActivateDVD()''
    To copy to clipboard, switch view to plain text mode 

    ... and using the SIGNAL macro, I get the following:
    Qt Code:
    1. Object::connect: No such signal evilcpcInputVoiceSignals::signalSignature.toAscii().constData()
    2. Failed to connect input plugin'Voice' signal 'evilcpcSignalActivateDVD()' to menu item plugin 'DVD' slot 'evilcpcSlotActivateDVD()''
    To copy to clipboard, switch view to plain text mode 
    Life without passion is death in disguise

  10. #9
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: reflection and qmetaobject

    Quote Originally Posted by wysota View Post
    SIGNAL and SLOT macros are a little hack Use this instead:
    Qt Code:
    1. QObject::connect(si, (QString("2")+signalSignature).toAscii().data(),
    2. sl, (QString("1")+slotSignature).toAscii().data());
    To copy to clipboard, switch view to plain text mode 
    Thanks, that worked perfectly
    Life without passion is death in disguise

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.