qtqmlqtscript

Passing a QObject to an Script function with QJSEngine?


I'm trying to call a function in an external script while passing a QObject as a parameter.

My QObject is defined as this:

#ifndef INSERTVALUES_H
#define INSERTVALUES_H

#include <QObject>

struct insertValueDef
{
  QString name;
  QString xmlCode;
  QString value;
  bool key;
  bool insert;
};
typedef insertValueDef TinsertValueDef;

class insertValues : public QObject
{
    Q_OBJECT
public:
    explicit insertValues(QObject *parent = 0);
    ~insertValues();
    void insertValue(TinsertValueDef value);
    int count();

    void setItemName(int index, QString name);
    void setItemXMLCode(int index, QString xmlCode);
    void setItemValue(int index, QString value);
    void setItemIsKey(int index, bool isKey);
    void setItemToInsert(int index, bool toInsert);

    QString itemName(int index);
    QString itemXMLCode(int index);
    QString itemValue(int index);
    bool itemIsKey(int index);
    bool itemToInsert(int index);

    bool valueIsNumber(int index);
    int getIndexByColumnName(QString name);

private:
    QList<TinsertValueDef> m_insertList;
};

#endif // INSERTVALUES_H

My JS Script function is this:

function beforeInsert(table,data)
{
  if (table == "tmpTable")
  {
    var index = data.getIndexByColumnName("tmpfield");
    if (index >= 0)
    {
     data.setItemValue(index,"Carlos Quiros"); 
    }
  }
}

The code that runs runs the script is the following:

QFile scriptFile(javaScript);
        if (!scriptFile.open(QIODevice::ReadOnly))
        {
            log("Error: Script file defined but cannot be opened");
            return 1;
        }
        JSEngine.evaluate(scriptFile.readAll(), javaScript);
        scriptFile.close();

        insertValues insertObject;

        TinsertValueDef tfield;
        tfield.key = false;
        tfield.name = "tmpfield";
        tfield.xmlCode = "tmpCode";
        tfield.value = "tmpValue";
        tfield.insert = true;
        insertObject.insertValue(tfield);
        QString error;

        beforeInsertFunction = JSEngine.evaluate("beforeInsert",error);

        if (!beforeInsertFunction.isError())
        {
            QJSValue insertListObj = JSEngine.newQObject(&insertObject);
            QJSValue result = beforeInsertFunction.call(QJSValueList() << "tmpTable" << insertListObj);
            if (result.isError())
            {
                log("Error calling BeforInsert JS function.");
                return 1;
            }
            else
            {
                log("JS function seems to be ok");
                for (int pos = 0; pos < insertObject.count(); pos++)
                {
                    log(insertObject.itemName(pos) + "-" + insertObject.itemValue(pos));
                }
                return 1;
            }
        }
        else
        {
            log("Error evaluating BeforInsert JS function. [" + error + "]");
            return 1;
        }

I can see that the parameter "table" is passing properly but the rest of the code is not working. I guess I cannot do:

var index = data.getIndexByColumnName("tmpfield");

Any idea what am I doing wrong? and what else should I do to make it work?

Thanks,


Solution

  • In order to access properties or invoke methods of QObjects passed to QJSEngine (or to QML), you need to declare them using Q_PROPERTY and Q_INVOKABLE macros in your QObject-derived class declaration.

    Please see the Qt documentation for more details: Exposing Attributes of C++ Types to QML