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

String-Based and Functor-Based Connections



  • Hi all,

    According to this for implicit type conversions and lambda expressions, we are expected to opt for the new syntax. Even for using default parameters we can once again make use of lambda to work it out. So for about %75 of the times we prefer the new style. But for connecting C++ functions to QML functions we still need string-based connections.

    Apart from this last point, in connections like this, we can't simply replace:

    // String-based syntax
        connect(slider, SIGNAL(valueChanged(int)),
                lcd, SLOT(display(int)));
    

    with

    // Functor-based syntax
        connect(slider, &slider::valueChanged,
                lcd, &lcd::display);
    

    Because display has three versions and the above connection can't recognize the int one to match. Right?

    QLCDNumber::display(int)
    QLCDNumber::display(double)
    QLCDNumber::display(QString)
    

  • Qt Champions 2017

    You can, however you have to cast the method pointer, because otherwise the compiler doesn't know which method you mean. This applies both to overloaded signals and overloaded slots. To do that you have 4 options (examples for the signal, but apply the same way to the slot if needed).

    1. Use the template parameters of connect to force the types (which isn't recommended, so I'm not going to provide a snippet)
    2. Static cast the type explicitly (rather ugly):
    connect(slider, static_cast<void (decltype(slider)::*)(int)>(&slider::valueChanged), lcd, &lcd::display);
    
    1. Use qOverload if you have c++14 compliant compiler, for example:
    connect(slider, qOverload<int>(&slider::valueChanged), lcd, &lcd::display);
    

    https://doc.qt.io/qt-5/qtglobal.html#qOverload

    1. Use QOverload::of if you're stuck to c++11:
    connect(slider, QOverload<int>::of(&slider::valueChanged), lcd, &lcd::display);
    

    https://doc.qt.io/qt-5/qtglobal.html#qOverload



  • @kshegunov

    Thanks so much for your time. :)
    I pick out the third version (marked as 2) with qOverload and C++ 14.
    But two questions: first why have you used qOverload for slider not for display?
    I thought it would be:

    connect(slider, &slider::valueChanged, lcd, qOverload<int>(&lcd::display));
    

    I'm using MinGW 3.7.0 64/32 bit, which is with the last Qt version. How to know what version of C++ it supports, please? We now can use C++20 on some compilers.

    And last, for connecting C++ functions to QML functions we still need string-based connections. So it's the last thing biding us to the old-version yet!


  • Qt Champions 2017

    @tomy said in String-Based and Functor-Based Connections:

    But two questions: first why have you used qOverload for slider not for display?

    Just for illustration purposes. You do it where you have an overloaded method regardless of it being a signal or slot. As I didn't have any information about your classes, I opted for the signal just to show the syntax.

    I'm using MinGW 3.7.0 64/32 bit, which is with the last Qt version. How to know what version of C++ it supports, please?

    You should consult the compiler's page. I don't know, I don't follow the support MinGW provides is all. This page:
    https://en.cppreference.com/w/cpp/compiler_support
    would be useful as well I imagine.

    We now can use C++20 on some compilers.

    Indeed.

    And last, for connecting C++ functions to QML functions we still need string-based connections.

    Yes, but unless QML switches to C++ (which it's supposed to at some point as far as I heard) we are going to be stuck with that limitation.



  • @kshegunov

    What compiler do you use on your Qt, please? Any why?
    The one I have on my Qt Creator, MinGW (the Windows version of GCC), is on the top of the list to support even cpp20. :)

    unless QML switches to C++

    What do you exactly mean, please?
    QML, as you know, uses cpp, JS, OpenGL, and more. What could switching to cpp mean?


  • Qt Champions 2017

    @tomy said in String-Based and Functor-Based Connections:

    What compiler do you use on your Qt, please? Any why?

    I develop on linux, so I use gcc (currently gcc 9.x). For windows where I just build and test I use msvc (if the client wants it), otherwise I use mingw, but the latter is pretty much compatible with what I see on linux.

    What do you exactly mean, please?

    As far as I recall (and take this with a grain of salt), instead of having the code in JS for the next QML iteration the actual code is going to be compiled in C++ and we are going to be able to tweak it (similar to the ordinary widgets). Which in my opinion is going to be a huge and appreciated step forward.



  • @kshegunov

    Thanks for your nice info.

    be compiled in C++

    I thought all code on a QtQuick project would be compiled by the cpp compiler (to bytecode) and then run!
    Did you mean to "replace JS code with cpp" in the next version, please?


  • Qt Champions 2017

    @tomy said in String-Based and Functor-Based Connections:

    I thought all code on a QtQuick project would be compiled by the cpp compiler (to bytecode) and then run!

    Yes, but generally the JS is going to be run through an interpreter at runtime (unless using the special compiler). In any case the point is that you tie the whole QML through the bindings and JS, and use C++ as a supplementary role to expose just a couple of classes/models to feed the UI.

    Did you mean to "replace JS code with cpp" in the next version, please?

    Not exactly, I meant provide a way to use C++ as the basis (a public API), and then just put the JS as an extension (not like now where the JS is leading, while C++ is just kind of the background supplementary - i.e. you register C++ objects to the QML engine). This's been a major complaint for a long time (mine included), that there's no C++ API to use as a primary means of using QML.



  • @kshegunov
    I got the things.

    interpreter at runtime (unless using the special compiler).

    Does it, surprisingly, mean if we pick out a special compiler, all code including the JS part, will be run by the machine, omitting the interpreter, thus better performance and speed!?
    If so, what is that compiler, please?


  • Qt Champions 2017

    @tomy said in String-Based and Functor-Based Connections:

    If so, what is that compiler, please?

    Here: https://doc.qt.io/QtQuickCompiler/
    I think it used to be a commercial offering, I don't know what's the license currently, though.



  • @kshegunov

    My QtQuick projects nearly always contain a .qrc file. And if not I add one to protect the source code.
    But to make the QtQuick compiler to do its job and we have better performance for the app when it's installed on the target device, is it enough, apart from having the .qrc file, to add the CONFIG line in the .pro file this way: CONFIG += c++11, qtquickcompiler, and then build the project please?

    If further explanations or more steps are needed, so let's have a separate thread for that. And I will make this thread as solved. :)


  • Qt Champions 2017

    @tomy said in String-Based and Functor-Based Connections:

    But to make the QtQuick compiler to do its job and we have better performance for the app when it's installed on the target device, is it enough, apart from having the .qrc file, to add the CONFIG line in the .pro file this way: CONFIG += c++11, qtquickcompiler, and then build the project please?

    I honestly have no idea, sorry. I have never worked or used the Qt Quick Compiler, I only know it exists. You need to explore it on your own or hope one of the QML aficionados pitches in. As an advice - yes, open a new topic in the QML section, where it's more probable to get some exposure for your question.



  • @kshegunov

    OK, sure. :)
    Thanks for your time.


Log in to reply