View Full Version : QtScript: Properties of the object inherited from QObjectList are not visible from JS

18th September 2012, 13:34
I'm trying to expose to JS the audioTracks object which should be accessible from JS as array (audioTracks[index]) and at the same time should have method audioTracks.getTrackById("id").
Here is my object:

class AudioTrackList : public QObject, public QObjectList


Q_PROPERTY(int length READ size SCRIPTABLE true)

Q_INVOKABLE QObject* getTrackById(QString id);

ScriptableIfaceMedia* m_impl;
QScriptEngine m_engine;


The problem is that when I expose the object in the following way:

Q_PROPERTY(QObjectList audioTracks READ audioTracks SCRIPTABLE true)
QObjectList audioTracks();

QObjectList MediaTracks::audioTracks()
int i;

QScriptValue rv = m_engine.newArray(m_audio_tracks->size());
for (i = 0; i < m_audio_tracks->size(); i++) {
rv.setProperty(i, m_engine.newQObject(m_audio_tracks->at(i), QScriptEngine::QtOwnership));

return static_cast<QObjectList>(*m_audio_tracks);

I have audioTracks[index] working but audioTracks.getTrackById("id") not.
Instead when I expose the object another way:

Q_PROPERTY(QObject* audioTracks READ audioTracks SCRIPTABLE true)
QObject* audioTracks();

QObject* MediaTracks::audioTracks()
m_engine.newQObject(m_audio_tracks, QScriptEngine::QtOwnership);
return m_audio_tracks;

I have audioTracks.getTrackById("id") working but audioTracks[index] not.
Is there any way to export my object to make it possible to access it from JS both like array and like object?

19th September 2012, 14:07
After having introduced the qobject into script, get hold of the array QScriptValue. The idea is to introduce a native function to the the qobject.

QScriptValue arrayVal = objectScriptVal.property(QString("propertyName"));
QScriptValue someFunctionName(QScriptContext *ctx, QScriptEngine *eng)
QObject* obj = ctx->thisObject()->toQObject();
if (obj){
MyClass* myClassObj = qobject_cast<MyClass*>(obj);
QObject* result = myClassObj->function(ctx->argument(0).toString());
return result; // or return eng->newQObject(result); //both should work
arrayVal.setProperty("functionName", engine->newFunction(someFunctionName));

In jist: here what has been done.
1. Introduced object with an array property.
2. Got hold of QScriptValue of array property.
3. Introduce a native function to the array property.

20th September 2012, 10:25
Still can't make it to work :(
pkj, did you manage to do such trick?
It seems that when my AudioTrackList is exposed to JS like array (by newArray()) then only standard JS array methods and properties are accessible.
When I try to call getTrackById() method I get such error: TypeError: 'undefined' is not a function (evaluating 'p.audioTracks.getTrackById("id1")')

20th September 2012, 13:12
I just found out that when I expose my object by QScriptEngine::newArray() I can't add to my object even a simple property like:

Q_PROPERTY(int myprop READ myprop SCRIPTABLE true)
int myprop() const;

In JavaScript it becomes a usual array.

2nd October 2012, 18:39
I have found a solution for my problem.
Since in JavaScript .0 and ['0'] are the same things I made the following workaround in my code:

value = m_engine.newQObject(m_audio_tracks, QScriptEngine::QtOwnership);
for (i = 0; i < m_audio_tracks->tracks().size(); i++) {
m_audio_tracks->setProperty(QString("%1").arg(i).toLocal8Bit().data(), qVariantFromValue(m_audio_tracks->tracks().at(i)));
value.setProperty(QString("%1").arg(i), m_engine.newQObject(m_audio_tracks->tracks().at(i), QScriptEngine::QtOwnership));

to make it possible to access my object like array from JavaScript.