向Qt脚本引擎公开一个基于模板的容器类

Expose a template-based container class to Qt script engine?

本文关键字:一个 于模板 容器类 脚本 Qt 引擎      更新时间:2023-10-16

情况

我有几个QVector<MyClass>的实例,我希望它们暴露给QScriptEngine

在我的项目中,MyClass是一个多维数据的缓存;点";,它看起来像:

class MyClass
{
public:
    MyClass();
    /*
        Some functions
    */ 
private:
    int m_index;
    double m_time;
    QList<int> *m_data;
};

我这样做的原因是因为我希望用户能够编写一些ECMA脚本来处理这些";点";它来自不同的集合。


问题

如何向Qt脚本引擎公开整个容器及其内容

我知道我可以将MyClass设为QObject,并调用QScriptEngine::newObject以获得它的QScriptValue,然后将值设置为引擎的全局对象。但这只会暴露";一点";到脚本引擎,我需要的是传递QVector<MyClass>的整个实例。

(任何其他类型的解决方法也很好!(

其中一个应该有效:

  1. 您可以将MyClass作为QObject,然后使用QScriptEngine::newArray创建一个显式数组,为数组中的每个对象调用QScriptEngine::newObject,并将脚本值添加到数组中;对于所有矢量,您都有

  2. 您可以将矢量类型注册到脚本引擎

    qScriptRegisterSequenceMetaType<QVector<MyClass> >(engine)
    
  3. 您可以创建自己的脚本值类型:

    Q_DECLARE_METATYPE(QVector<MyClass>);
    qRegisterMetaType<QVector<MyClass> >();  
    qScriptRegisterMetaType<QVector<MyClass> >(engine, qScriptValueFromVector, qScriptValueToVector, QScriptValue());
    //arbitrary conversion functions (you could also create a new object, with a pointer to a vector):
    QScriptValue qScriptValueFromVector(QScriptEngine *engine, QVector<MyClass> const &list)
    {  
        QScriptValue result = engine->newArray(list.size());
        for (int i=0;i<list.size();i++)
            result.setProperty(i,  engine->newQObject(list[i])); 
        return result;
    }
    void qScriptValueToStringPtr(const QScriptValue &value, QVector<MyClass> &list) {
        list.clear();
        QScriptValueIterator it(def);
        while (it.hasNext()) {
            it.next();
            if (it.flags() & QScriptValue::SkipInEnumeration)
                continue;
            list << *it.value().toQObject();
        } 
    }