Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 5

Qt-interest Archive, February 2008
QtScript - creating/passing QObject classes from within script


Message 1 in thread

Here's another hopefully simple question. The documentation is a bit 
erratic on this topic. What I'm looking at doing is using QtScript to 
"set up" my object model when my app starts up, as a method of rapid 
prototyping.

I want to expose some QObject-derived classes to the scripting system, 
so I can do something like this:

    var mo = new MyObject();
    globalObject.addMyObject(mo);

I've got the first line working, with this bit of code:

static QScriptValue myObject_construct(QScriptContext *ctx, 
QScriptEngine *engine)
{
     return engine->newQObject(
         new MyObject(),
         QScriptEngine::AutoOwnership);
}

QScriptValue moType = engine.newQMetaObject(&MyObject::staticMetaObject, 
engine.newFunction(myObject_construct, 0));
engine.globalObject().setProperty(
     "MyObject",
     engine.newQMetaObject(&MyObject::staticMetaObject,
         engine.newFunction(myObject_construct, 0)));


Now, I've exposed my "global" object (globalObject) with this piece of code:

GlobalObject go;
engine.globalObject().setProperty(
     "globalObject",
     engine.newQObject(&go));

But, in the script, when I call addMyObject(), I get this exception:

uncaught exception at line -1: TypeError: cannot call addMyObject(): 
unknown type `MyObject*'



What did I miss?

-- 
 [ signature omitted ] 

Message 2 in thread

Paul Miller wrote:
> Here's another hopefully simple question. The documentation is a bit
> erratic on this topic. What I'm looking at doing is using QtScript to
> "set up" my object model when my app starts up, as a method of rapid
> prototyping.
>
> I want to expose some QObject-derived classes to the scripting system,
> so I can do something like this:
>
>    var mo = new MyObject();
>    globalObject.addMyObject(mo);
[...]
> But, in the script, when I call addMyObject(), I get this exception:
>
> uncaught exception at line -1: TypeError: cannot call addMyObject():
> unknown type `MyObject*'
>
>
>
> What did I miss?
>


Hi Paul,
MyObject* is not a built-in type, so QtScript doesn't know how to
convert a script value to that type. The easiest solution is to change
your GlobalObject::addMyObject() function to take a QObject* argument
instead, or QWidget* if your objects are widgets (these are both
built-in types). If necessary, you can use qobject_cast to do
type-checking in your function. The alternative solution is to install
your own conversion functions for MyObject* with qScriptRegisterMetaType().

Regards,
Kent


--
 [ signature omitted ] 

Message 3 in thread

Kent Hansen wrote:
> Paul Miller wrote:
>   
>> But, in the script, when I call addMyObject(), I get this exception:
>>
>> uncaught exception at line -1: TypeError: cannot call addMyObject():
>> unknown type `MyObject*'
>>
>>
>>
>> What did I miss?
>>
>>     
>
>
> Hi Paul,
> MyObject* is not a built-in type, so QtScript doesn't know how to
> convert a script value to that type. The easiest solution is to change
> your GlobalObject::addMyObject() function to take a QObject* argument
> instead, or QWidget* if your objects are widgets (these are both
> built-in types). If necessary, you can use qobject_cast to do
> type-checking in your function. The alternative solution is to install
> your own conversion functions for MyObject* with qScriptRegisterMetaType().
>   

Actually there's a better alternative in this particular case; you just
have to make MyObject* known to the meta-type system.


Q_DECLARE_METATYPE(MyObject*)

...

qMetaTypeId<MyObject*>();


Then it should "just work" with the rest of your code as-is. We'll try
to improve the docs on this subject.

Regards,
Kent

--
 [ signature omitted ] 

Message 4 in thread

Kent Hansen wrote:
>> MyObject* is not a built-in type, so QtScript doesn't know how to
>> convert a script value to that type. The easiest solution is to change
>> your GlobalObject::addMyObject() function to take a QObject* argument
>> instead, or QWidget* if your objects are widgets (these are both
>> built-in types). If necessary, you can use qobject_cast to do
>> type-checking in your function. The alternative solution is to install
>> your own conversion functions for MyObject* with qScriptRegisterMetaType().
>>   
> 
> Actually there's a better alternative in this particular case; you just
> have to make MyObject* known to the meta-type system.
> 
> 
> Q_DECLARE_METATYPE(MyObject*)
> ...
> qMetaTypeId<MyObject*>();
> 
> Then it should "just work" with the rest of your code as-is. We'll try
> to improve the docs on this subject.

It does! I'm curious why making my subclass a Q_OBJECT doesn't 
automatically do this for me.


-- 
 [ signature omitted ] 

Message 5 in thread

Paul Miller wrote:
> Kent Hansen wrote:
>> Actually there's a better alternative in this particular case; you just
>> have to make MyObject* known to the meta-type system.
>>
>>
>> Q_DECLARE_METATYPE(MyObject*)
>> ...
>> qMetaTypeId<MyObject*>();
>>
>> Then it should "just work" with the rest of your code as-is. We'll try
>> to improve the docs on this subject.
>
> It does! I'm curious why making my subclass a Q_OBJECT doesn't
> automatically do this for me.
>
>


Indeed, it's possible to make this work without the hassle. I've created
a task for this issue, you can track it at
http://trolltech.com/developer/task-tracker/index_html?id=200599&method=entry
(the link won't go "live" for a few hours yet).

Regards,
Kent

--
 [ signature omitted ]