如何使用可选参数编​​写Q_INVOKABLE函数?

时间:2018-12-19 15:40:32

标签: qt qml

这是我的C ++函数

头文件:

Q_INVOKABLE void setSelection(qint64 start, qint64 end, qint64 init);

主体文件:

void SelectionModel::setSelection(qint64 start, qint64 end, qint64 init) { 
    ...
}

如何将init参数修改为可选参数,以便

A)

我可以通过以下两种方式之一从JavaScript调用该函数:

setSelection(0, 10, 4)
setSelection(0, 10)

B)

我可以在C ++代码中找出是否已传递init参数。

3 个答案:

答案 0 :(得分:2)

A)只需将默认值设置为第三个参数即可:

Q_INVOKABLE void setSelection(qint64 start, qint64 end, qint64 init = 0);

B)您无法区分,尽管有一个技巧可以将默认值设置为不应使用的值,例如,如果输入采用正值,则可以将默认值设置为-1,这样您就可以区分。

答案 1 :(得分:2)

另外2个答案很好。要点是,您无法在C ++中知道是否已传递默认参数。

有时候,您可以牺牲使用类型范围的某些部分来检测默认值:shiped_at

使用C ++ 17,我们现在有了一种新的机制,可以在不牺牲范围的情况下处理此类情况:

void f(int somethingThatShouldBePositive = -1)

但是,它不适用于QML(或Qt元类型系统),因此您需要将其包装:

void f(std::optional<int> a = std::optional<int>()) {
    if (!a.has_value()) {
         // f was called like this: f()
    } else {
        // f was called like this f(-1) or f(10)
    }
}

从QML呼叫:

Q_INVOKABLE void f(int a, int b) {
    qDebug() << Q_FUNC_INFO;
    f(a, b, std::optional<int>{});
}
Q_INVOKABLE void f(int a, int b, int c) {
    qDebug() << Q_FUNC_INFO << a << b << c;
    f(a, b, std::optional<int>{ c });
}
Q_INVOKABLE void f(int a, int b, std::optional<int> c){
    qDebug() << Q_FUNC_INFO << a << b << c.has_value();
}

产生以下输出:

        obj.f(1,1);
        obj.f(1,2,3);

这正是您想要的,但是我建议您仅在无法使用其他答案的情况下这样做。

答案 2 :(得分:1)

您可以添加一个重载,如下所示:

Q_INVOKABLE void setSelection(qint64 start, qint64 end);
Q_INVOKABLE void setSelection(qint64 start, qint64 end, qint64 init);

重载实现:

void SelectionModel::setSelection(qint64 start, qint64 end) { 

  //here you know init hasn't been passed ...

  setSelection(start, end, 0);
}