PDA

View Full Version : [Advanced] Qt Script access QObject from C++ code



bunjee
20th May 2009, 12:38
Hey guys,

I'm using the Qt script bindings from Qt Labs.

I'm writing the following lines in my script :


function main() {}

main.prototype.createPage = function()
{
box = new QWidget; // I need that QWidget pointer in my C++ code
}

I'm calling this function from C++ code.
Afterward, I need to gather all references to Qt Objects.

How can I do that ?

Thanks.

wysota
20th May 2009, 12:44
You can have a function in script that keeps references to all objects created and you can assign a function to the global object of the engine that will return a list of them. Then it's just a matter of calling that function using QScriptEngine::evaluate() and interpreting the resulting QScriptValue as a list of objects.

bunjee
20th May 2009, 12:47
You can have a function in script that keeps references to all objects created.

Sounds good, how can I do that ? (I want this to be transparent)

wysota
20th May 2009, 23:47
Call it from the function you pasted in your previous post just before returning the object or modify the prototype of each class you want managed directly.

bunjee
21st May 2009, 22:27
I did it this way:

Qt script code:

function New(This, object)
{
if (!This.objects) This.objects = new Array;

This.objects.push(object);
return object;
}

function objects() { return this.objects; } // Getting objects from C++

...
box = New(this, new QWidget);
...

C++ code:


void qkScriptPrivate::updateObjects()
{
Q_Q(qkScript);

QScriptValue objects = engine->globalObject().property("objects");
QScriptValue output = objects.call(scriptValue);

QScriptValueIterator it(output);
while (it.hasNext())
{
it.next();

if (it.value().isQObject()) q->declareObject(it.value().toQObject());
qkPrint("%s : %s", it.name().C_STR, it.value().toString().C_STR);
}
}

Note that you can make it fully transparent by parsing every "new myObject" in the script and replace it by "New(this, new myObject)".

wysota
21st May 2009, 23:10
Great, that's exactly what I meant :)