PDA

View Full Version : QtScript binding wrappers? An Easy Way?



Statix
25th June 2010, 13:28
I've been struggling with figuring out how to wrap the QtScript bindings (or anything else for that matter) so that the base class properties and slots are still visible to my newly created QtScript object.

For example in QtScript using bindings created by the QtBindingsGenerator I can do the following:


var page = new QWizardPage();
var layout = new QGridLayout();
page.setLayout(layout); //setLayout is actually defined in QWidget and it is accessible here

However I need access to 'protected' functionality of QWizardPage so I've been trying to create a wrapper to expose these methods without removing existing things I can call from QtScript.


class ScriptWizardPage : public QWizardPage
{
Q_OBJECT;
...
public:
Q_INVOKABLE void registerField(...);
};
Q_SCRIPT_DECLARE_QMETAOBJECT(ScriptWizardPage, QWidget*);

//Adding to engine
QScriptValue newClass = engine->scriptValueFromQMetaObject(ScriptWizardPage>();
engine->globalObject().setProperty("ScriptWizardPage", newClass);


By creating the ScriptWizardPage i can now access the 'registerField' method in QtScript however all of the previously exposed methods such as setLayout() are removed and I am unaware of how to keep them there without completely wrapping all functionality of a QWizardPage all the way down to QWidget -- there must be a better, less tedious way that eludes me!?

JohannesMunk
25th June 2010, 21:25
Hi there!

Are you aware of the scriptshell? There is a good chance that your protected method that you want to expose is already exposed.

look into .. /QtScriptBindingsGenerator/generated_cpp/com_trolltech_qt_gui/qtscriptshell_QWizardPage.cpp

you just create a function property inside QtScript with the same name, that is then called.

If you also want to call the implementation of the base class have a look at my post regarding this:

http://www.qtcentre.org/threads/29044-QtScript-Bindings-Generator-ScriptShell-Event-Binding (http://www.qtcentre.org/29044-QtScript-Bindings-Generator-ScriptShell-Event-Binding)

If all that doesn't work for you.. you could try to assign a QWizardPage Scriptobject as prototype to yours.

Johannes

Statix
27th June 2010, 15:37
I checked in the QWizardPage.cpp for that same file and didn't find the method I wanted (specifically http://doc.qt.nokia.com/4.6/qwizardpage.html#registerField and its friends).

I don't think i can change the binding generator due to its license restrictions on my project so I think my last method is the ' QWizardPage Scriptobject as prototype' suggestion however that is the part I'm most unclear on.

In order to do that I need to setDefaultPrototype before exposing my ScriptWizardPage wrapper to QtScript or afterward in the code (not ideal for me).

Can you elaborate? I haven't been able to entirely grasp prototypes in QtScript :D

JohannesMunk
27th June 2010, 17:03
I never actually had to do it before either, but have a look at how the bindings do it:

excerpt from qtscript_QWizardPage.cpp:


QScriptValue qtscript_create_QWizardPage_class(QScriptEngine *engine)
{
...
engine->setDefaultPrototype(qMetaTypeId<QWizardPage*>(), QScriptValue());
QScriptValue proto = engine->newVariant(qVariantFromValue((QWizardPage*)0));
proto.setPrototype(engine->defaultPrototype(qMetaTypeId<QWidget*>()));
for (int i = 0; i < 14; ++i) {
QScriptValue fun = engine->newFunction(qtscript_QWizardPage_prototype_call, function_lengths[i+1]);
fun.setData(QScriptValue(engine, uint(0xBABE0000 + i)));
proto.setProperty(QString::fromLatin1(qtscript_QWi zardPage_function_names[i+1]),
fun, QScriptValue::SkipInEnumeration);
}

qScriptRegisterMetaType<QWizardPage*>(engine, qtscript_QWizardPage_toScriptValue,
qtscript_QWizardPage_fromScriptValue, proto);


You need to get the prototype of the QWizardPage, set it as prototype of your own class and add the function calls you need.

HIH

Joh