【问题标题】:Javascript function as QML property defined from c++作为从 c++ 定义的 QML 属性的 Javascript 函数
【发布时间】:2017-08-13 09:20:57
【问题描述】:

我在 c++ 中定义了以下 QML 对象:

class MyObj : public QQuickItem {
    Q_OBJECT
    Q_PROPERTY(QVariant func MEMBER func)

public slots:
    void callFunc(){
        //Call function pointed by "func" somehow
    }

private:
    QVariant func;
};

在 QML 中我使用MyObj 如下:

MyObj{
    func: function test(){ console.log("Hi!"); }

    Button{
        text: "Call func"
        onClicked: parent.callFunc()
    }
}

我收到以下错误:

Unable to assign a function to a property of any type other than var.

我不明白,QVariant 属性不应该与property var 相同吗?这样做的正确方法是什么?

【问题讨论】:

    标签: javascript c++ qml function-pointers qtquick2


    【解决方案1】:

    您可以为此使用QJSValue。 Qt Quick Controls 2的SpinBoxdoes something similar

    Q_PROPERTY(QJSValue textFromValue READ textFromValue WRITE setTextFromValue NOTIFY textFromValueChanged FINAL)
    

    它的 getter 和 setter 是这样实现的:

    QJSValue QQuickSpinBox::textFromValue() const
    {
        Q_D(const QQuickSpinBox);
        if (!d->textFromValue.isCallable()) {
            QQmlEngine *engine = qmlEngine(this);
            if (engine)
                d->textFromValue = engine->evaluate(QStringLiteral("function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }"));
        }
        return d->textFromValue;
    }
    
    void QQuickSpinBox::setTextFromValue(const QJSValue &callback)
    {
        Q_D(QQuickSpinBox);
        if (!callback.isCallable()) {
            qmlInfo(this) << "textFromValue must be a callable function";
            return;
        }
        d->textFromValue = callback;
        emit textFromValueChanged();
    }
    

    如果没有给出,getter 会提供一个默认的函数实现(或者该值实际上不是一个函数)。

    函数is used 允许用户为给定的输入值返回自定义文本:

    text: control.textFromValue(control.value, control.locale)
    

    documentation 为例,以下是您分配/覆盖函数的方式:

    SpinBox {
        id: spinbox
        from: 0
        value: 110
        to: 100 * 100
        stepSize: 100
        anchors.centerIn: parent
    
        property int decimals: 2
        property real realValue: value / 100
    
        validator: DoubleValidator {
            bottom: Math.min(spinbox.from, spinbox.to)
            top:  Math.max(spinbox.from, spinbox.to)
        }
    
        textFromValue: function(value, locale) {
            return Number(value / 100).toLocaleString(locale, 'f', spinbox.decimals)
        }
    
        valueFromText: function(text, locale) {
            return Number.fromLocaleString(locale, text) * 100
        }
    }
    

    【讨论】:

    • 感谢这项工作。在问这个问题之前,我实际上已经尝试过Q_PROPERTY(QJSValue func MEMBER callback),但这以某种方式给出了错误:invalid new-expression of abstract class type ‘QQmlPrivate::QQmlElement&lt;MyObj&gt;’ 在编译期间。然后我假设属性不能是QJSValue 类型。
    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多