Qt/Qml and method overloads

只愿长相守 提交于 2019-12-09 09:22:58

问题


Just came across a weird behavior of Qt framework while invoking overloaded C++ methods from within Qml and trying to understand the reason behind it. Let's say I have a QList<QVariant>-like class with the following methods:

...
Q_SLOT void append(const QVariant &item);
Q_SLOT void append(const QVariantList &items);
Q_SLOT void insert(int index, const QVariant &item);
Q_SLOT void insert(int index, const QVariantList &items);
...

Qml:

onclicked: {
  var itemCount = myListObject.size();
  myListObject.insert(itemCount, "Item " + (itemCount + 1));
}

Qt somehow decides to invoke the void insert(int index, const QVariantList &items) overload with items argument set to a null QVariant an empty QVariantList instead of the void insert(int index, const QVariant &item) overload with QString wrapped in QVariant.

Now if I change the order of declarations as follows, it works as expected:

Q_SLOT void insert(int index, const QVariantList &items);
Q_SLOT void insert(int index, const QVariant &item);

I could not find anything under Qt framework's documentation regarding the order of declarations and how it affects the way methods are resolved during invoke.

Can someone please explain? Thank you.


回答1:


This question is related to overloading in JavaScript. Once you get to known with it -- you understand reason of "weird behavior" of your code. Just take a look at Function overloading in Javascript - Best practices.

In few words -- I recommend you to do next: since you can operate QVariant variables on both sides (QML and Qt/C++) -- pass variant as parameter, and process it on Qt/C++ side as you wish.

You can use something like this:

Your C++ class created and passed to QML (e.g. as setContextProperty("TestObject", &tc)):

public slots:
    Q_SLOT void insert(const int index, const QVariant &something) {
        qDebug() << __FUNCTION__;
        if (something.canConvert<QString>()) {
            insertOne(index, something.toString());
        } else if (something.canConvert<QStringList>()) {
            insertMany(index, something.toStringList());
        }
    }

private slots:
    void insertOne(int index, const QString &item) {
        qDebug() << __FUNCTION__ << index << item;
    }

    void insertMany(int index, const QStringList &items) {
        qDebug() << __FUNCTION__ << index << items;
    }

Somewhere in your QML:

Button {
    anchors.centerIn: parent
    text: "click me"
    onClicked: {
        // Next line will call insertOne
        TestObject.insert(1, "Only one string")
        // Next line will call insertMany
        TestObject.insert(2, ["Lots", "of", "strings"])
        // Next line will call insertOne
        TestObject.insert(3, "Item " + (3 + 1))
        // Next line will call insertOne with empty string
        TestObject.insert(4, "")
        // Next line will will warn about error on QML side:
        // Error: Insufficient arguments
        TestObject.insert(5)
    }
}


来源:https://stackoverflow.com/questions/28529776/qt-qml-and-method-overloads

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!