Qt5 & invokeMethod



  • Hello everyone,

    I have a - hopefully - simple question:

    Is there a Qt5 Syntax-conform way to call QMetaObject::invokeMethod ?

    For example I use something like this to call a function in the next event loop cycle:

    QMetaObject::invokeMethod(this, "myFunction" ,Qt::QueuedConnection);
    

    But it is highly inconvenient.

    • The function call is not listed wenn you search for it!
    • Because "myFunction" is essentially a string, its not effected by simple refactoring e.g renaming.
    • And of course no compile-time validation check

    I know I could potentially use a QTimer:

    QTimer::singleShot(0,this, &myClass::myFunction);
    

    But that feels like circumventing the problem, also I'm nut sure if those 2 would always behave in the same way!


  • Moderators

    @J.Hilk
    the 2 methods behave the same.
    QMetaObject::invokeMethod() only accepts the method as string because it is using the object's metaObject, which also only stores the methods as string.
    You can check the return value of invokeMethod() and add an assertion.

    bool check = QMetaObject::invokeMethod(...);
    Q_ASSERT( check );
    

    Just make sure not to surround the invokeMethod() call into Q_ASSERT otherwise they wont be executed in release mode.
    But you could add your custom assertion macro for this as well:

    #ifdef QT_DEBUG
    #define MY_ASSERT(CODE) Q_ASSERT(CODE);
    #else
    #define MY_ASSERT(CODE) CODE
    #endif
    
    MY_ASSERT( QMetaObject::invokeMethod(...) );
    

    or alternatively for both debug AND release (untested though - not sure if this compiles):

    #define MY_ASSERT(CODE) (CODE == false ? (qFatal() << #CODE << wasn't successful;) : (void;) )
    
    MY_ASSERT( QMetaObject::invokeMethod(...) );
    

  • Moderators

    In Qt 5.10 (currently in alpha) there's gonna be an overload taking pointer to function, so you'll be able to do:

    QMetaObject::invokeMethod(this, &myClass::myFunction, Qt::QueuedConnection);
    

    For now I'd use the timer. The 0 timeout special case is documented so there's nothing wrong in using it.



  • Thanks @raven-worx and @Chris-Kawa for the quick answers.

    @raven-worx said in Qt5 & invokeMethod:

    the 2 methods behave the same.

    I know that they seem to behave in the same way.
    But creating an timer object, running & processing the timer/timeout and deleteing the object afterwards, feels like it should be more work than queing a function call via Q_Object-Macro-Magic. However the compiler may break it down to the same thing, after all.

    @raven-worx said in Qt5 & invokeMethod:

    You can check the return value of invokeMethod() and add an assertion.

    That is actually a good idea, that way one would always get an immediate notification when the call becomes invalid due to changes made.
    Still inconvenient, but much less so.

    @Chris-Kawa said in Qt5 & invokeMethod:

    In Qt 5.10 (currently in alpha) there's gonna be an overload taking pointer to function, so you'll be able to do:

    YES, thanks for the info, I was not aware of that change.

    Now I'm hyped for Qt 5.10 more so than previously!

    With that said, I would consider my question answered.
    Thanks everyone.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.