Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

New style connect to non-slot function with default params?



  • Hi -

    I'm trying to connect a signal to a non-slot function in a Qobject, namely QScriptEngine. The class has these functions:

    @
    QScriptValue evaluate(const QString & program, const QString & fileName = QString(), int lineNumber = 1)
    QScriptValue evaluate(const QScriptProgram & program)
    @

    When trying to compile my connect function, the compiler complains:

    error: no matching function for call to ‘XAvionicsController::connect(XAvionicsController* const, void (XAvionicsController::)(QString), QScriptEngine&, <unresolved overloaded function type>)’

    I want to use the new style connect from Qt 5, but don't know how to tell it "hey, pick that one!" Unfortunately the function is not a slot or else I could use the old syntax.

    Am I just S.O.L?


  • Moderators

    Hi,

    There are 2 issues here.

    To tell the compiler which function to pick, you need to explicitly cast your function pointer (see Lukas Geyer's post at http://qt-project.org/forums/viewthread/21513 )

    The Qt5-style connections do not support default parameters. If you want to connect to the evaluate(QString, QString, int), then your signal must also have 3 parameters (QString, QString, int). Or, you can connect your signal to a custom slot that then calls evaluate().



  • Thanks!

    Part of my problem is that I mis-read the second overload - I thought it was taking in a QString, but rather it takes a QScriptProgram.

    I ended up changing the signal to have 3 parameters, and the connect looks like this:

    @
    connect(this, &XAvionicsController::executeScript,
    _pScriptEngine, static_cast<QScriptValue (QScriptEngine::*)(const QString &, const QString&, int)>(&QScriptEngine::evaluate));
    @

    Compiles at least, so it should work. Will report back if any problems occur when running.



  • If you want to use a function that has overloads and/or default parameters, you could also use a lambda expression in your connect statement. Connect to a lambda instead of the function, and call the function from the lambda. There, these overloads or default parameters are no problem any more.



  • Thanks, man. Do you think you could post some sample code?

    Also, as I'm thinking about it... the point of what I was doing is that I moved the QScriptEngine off to its own thread and when I emit the signal, the function gets invoked from the event loop of the thread it is on, as opposed to the main thread.

    If you do the lambda function, I think the function would get called on my thread, no?


  • Moderators

    Good call, Andre. I've now learnt a new way to use these tools today :)

    [quote author="medvedm" date="1391179075"]the point of what I was doing is that I moved the QScriptEngine off to its own thread and when I emit the signal, the function gets invoked from the event loop of the thread it is on, as opposed to the main thread.

    If you do the lambda function, I think the function would get called on my thread, no?[/quote]You can select the appropriate event loop (thread) using the "context" argument when connecting: http://qt-project.org/doc/qt-5/qobject.html#connect-6



  • I'm a total n00b with lamdas, a little help here?

    @
    connect(this,
    &XAvionicsController::executeScript,
    _pScriptEngine,
    [=](QString program) { _pScriptEngine->evaluate(program); },
    Qt::AutoConnection);
    @

    This doesn't compile...



  • Ah, on a hunch.... I'm using the current version of qt in ubuntu, 5.0.2, which does not have the connect overload referenced above.


  • Moderators

    [quote author="medvedm" date="1391182866"]Ah, on a hunch.... I'm using the current version of qt in ubuntu, 5.0.2, which does not have the connect overload referenced above.[/quote]You can install Qt 5.2.0, or implement a custom slot in a subclassed QScriptEngine.

    Your lambda syntax itself looks correct (although I'd use const QString& instead of QString to avoid unnecessary copying)



  • [quote author="JKSH" date="1391265817"](although I'd use const QString& instead of QString to avoid unnecessary copying)[/quote]

    Copying QString is cheap. It's a COW (implicitly shared) class, remember?

    In C++/11 with move semantics, passing by value may be faster than by reference in some cases.


Log in to reply