PDA

View Full Version : QScriptValue with simple typedef types



JohannesMunk
11th May 2009, 17:38
Hi there!

I can't get a simple typedefed type (like typedef CDB_ID quint32;) to work correctly as a QScriptValue / QVariant.

When I try to call a member function returning a CDB_ID from a qtscript, it always returns zero. Can anybody point me in the right direction?




typedef int CDB_ID;

Q_DECLARE_METATYPE(CDB_ID)

class SClass : public QObject
{ Q_OBJECT
public slots:
int TestA() {return 5;}
CDB_ID TestB() {return 8;}
};

QScriptValue CDB_IDToScriptValue(QScriptEngine *engine,const CDB_ID &in)
{
return engine->newVariant(QVariant::fromValue(in));
}

void CDB_IDFromScriptValue(const QScriptValue &object, CDB_ID &out)
{
out = object.toVariant().value<CDB_ID>();
}

..

QScriptEngine eng;
qRegisterMetaType<CDB_ID>("CDB_ID");
qScriptRegisterMetaType<CDB_ID>(&eng, CDB_IDToScriptValue, CDB_IDFromScriptValue);

SClass* s = new SClass();
QScriptValue obj = eng.newQObject(s);

// Return value as CDB_ID .. always returns 0!
fun = eng.evaluate("function() {return this.TestB();}");
res = fun.call(obj,QScriptValueList());
CDB_ID cdbid = 4;
CDB_IDFromScriptValue(res,cdbid);
qDebug() << "B: " << res.toString() << res.isVariant() << cdbid << " error: " << eng.uncaughtException().toString();



Attached you will find a working demo of my problem!

Thx a lot!

Johannes

wysota
14th May 2009, 01:30
Declaring a metatype for a typedef to int doesn't make much sense. CDB_ID is just an alias for int - you can mix the two freely so you can use CDB_ID just like if it was an int (because it IS an int). For example you can cast a variant to CDB_ID by using QVariant::toInt().

JohannesMunk
14th May 2009, 01:52
Hi there!

It makes sense to me, not because of type-safety, but because I want to be able to globally change the type later if required. Change to 64bit or something like that.. Over the years, I found it to be good practice to define those dedicated types..

A workaround could have been a #define, but then I found out, that moc ignores them.

Of course there is the option to use a struct, but thats overkill here.

For now.. I gave up and just used the built in types (quint32, ..) directly.. but that's not a nice solution..

Thx for your reply anyway.

Johannes

wysota
14th May 2009, 09:04
But you don't need any workaround. Ints just work, so use them. You can't declare a meta-object for a type that already has one and probably you can't declare a meta-object for something that is not a class.

JohannesMunk
14th May 2009, 12:47
Hi!

You didn't get me. I want to use a typedef for certain variables like IDs or TypeIDs to be able to change the type programmwide at one spot. Thats the basic idea of typedefs btw.. But as you said, thats probably not possible for non class/struct-types in combination with qtscript.

Cheers

Joh

wysota
14th May 2009, 13:14
I understand what you want. I just said that if you typedef to int, you shouldn't try to register its metatype. At some point you are making the typedef. At the same spot you can decide whether to register the metatype or not.

JohannesMunk
14th May 2009, 13:23
Ok. But if I don't register the metatype, I can't call methods with that return type or parameter from within qscript. Thats my problem. And as I see it, even with a #define instead of a typedef there is no way convincing moc to allow me to do that. Or is there?

wysota
14th May 2009, 13:59
I've been experimenting but I can't get it to work. But it's not moc that is to be blamed but QtScript. So it should just be a matter of convincing QtScript that it knows the typedefed type. I think it should be possible to do it if you implement a prototype for CDB_ID in the script engine.

JohannesMunk
14th May 2009, 14:17
Uha. And I thought.. the solution would be so obvious, that I posted in the Newbie forum ;)

In what way will a prototype help me here? If I understand the concept correctly, prototypes of a given value are used to resolve properties not found in the value itself. Which allows to implement some kind of inheritance. Do you suggest putting my CDB_ID-value into a property instead of the value directly? But each property is a QScriptValue again. How does that help me?

Thx for your efforts!

Johannes

wysota
14th May 2009, 15:07
A prototype in QtScript is an equivalent of class in C++. So creating a prototype for "CDB_ID" is an equivalent of creating a class in C++ code. In other words it should make QtScript familiar with CDB_ID. Then outside the script environment you'll be able to operate on CDB_ID script values depending on the actual type(def) of CDB_ID.