Important: Please read the Qt Code of Conduct -

How to pass variables as reference from C++ to QML

  • I need to expose a (slot) function from C++ into QML with parameters as reference to be used on the QML side:

    C++ side
    @class A : public QObject

    public slot:
    void func(int& i, QString& s);

    QML side
    @onClicked: {
    objectA.func(i,s) something with i something with s

    When I run the application, I receive an error message saying that javascript doesn't recognise i and s parameters. Any idea?

  • Make sure you have the Q_OBJECT macro in your header file (just because it is not in the listing you posted). For a slot, that should already do it, assuming you added objectA as a context property t to the QML context.

  • Yes Q_OBJECT and I'm exposing objectA as a context property.
    When I run the test I receive the following message:

    @Unknown method parameter type: int&

  • Hm, not sure. It is a bit awkward to see non-const references there. Does it work with const int&? Not that that makes a whole lot of sense.
    References in slot parameters feel weird since it is unknown how many receivers a slot has, so how would you know which signal was calling you? And then there are queued connections. And whatnot. Looks strange.

  • Don't you need the Q_INVOKABLE macro somehow?

  • Moderators

    in slots it's not necessary.

  • Thank you,

  • @miroslav: Conceptually you are right. But in this particular case, the slot isn't used in a signal & slot context, but it is being called directly from QML side. Saying that, it shouldn't be a problem to provide arguments as reference.
    In any case, I also tried making the function public and using Q_INVOKABLE to be exposed to QML and the result is the same.

    At the end, there is always work arounds to solve problems. In this case, I had to create 2 functions to provide the necessary paramenters as return values. But it is kind of duplication of code and CPU usage.

    is there an official location to make suggestion or bug reports to the active developers?

  • Moderators

  • You need to use QVariant when passing arguments to c++:

    void func(const QVariant &arg1, const QVariant &arg2) {
    int i = arg.toInt();
    QString s = arg.toString();

  • @richardmg: You don't need to use QVariant, no. When calling a function of a QObject from JavaScript, the QObject wrapper / interface class attempts to find the closest overload depending on the argument types.

    It's true that some argument types are unknown to the QML typesystem, and for those wrapping in QVariants may be necessary (although they'll be opaque to JavaScript code) but for other types, it is not necessary.

    Internally, basic types are indeed wrapped into QVariants when they're stored, but this should be transparent to the application programmer.

    @dmendizabal: object introspection allows code to dynamically look up your objects' methods at runtime, and arbitrarily connect signals to your slots. Thus, if you have a Q_SLOT, it must abide by the rules for signal/slot connection, regardless of whether your code specifically makes use of it.

    In most cases, for Qt built-in types, implicit sharing means that references are no cheaper than copies anyway.


Log in to reply