Results 1 to 3 of 3

Thread: How to really really use custom QtScript classes

  1. #1
    Join Date
    Apr 2012
    Location
    Vienna, Austria
    Posts
    17
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Question How to really really use custom QtScript classes

    Hello everybody

    i'm aiming for the following ecma scenario:
    Qt Code:
    1. var whatever = new myClass();
    2. whatever.whatreallyever();
    To copy to clipboard, switch view to plain text mode 

    So i want to use a custom c++, from QObject inherited class from within QtScript.

    ... after hours of consulting the documentation, forum threads and tried tons of experiments by myself - i still wasn't able to make any object available to a QScriptEngine like shown in the case above.

    So my question is, how can you implement some newable c++ object for QtScript and/or is there any minimal example for that case?

    What i've tried so far:
    1) Qt 4.8's customClass Example - doesnt compile under Qt5.3, mocking that
    Qt Code:
    1. ByteArrayClass *cls = qscriptvalue_cast<ByteArrayClass*>(ctx->callee().data());
    To copy to clipboard, switch view to plain text mode 
    results in:
    In file included from /usr/include/qt5/QtCore/qnamespace.h:45:0,
    from /usr/include/qt5/QtCore/qobjectdefs.h:45,
    from /usr/include/qt5/QtCore/qobject.h:48,
    from /usr/include/qt5/QtCore/QObject:1,
    from ../customClass/bytearrayclass.h:4,
    from ../customClass/bytearrayclass.cpp:2:
    /usr/include/qt5/QtCore/qobject.h: In instantiation of 'T qobject_cast(QObject*) [with T = ByteArrayClass*]':
    /usr/include/qt5/QtCore/qvariant.h:695:51: required from 'static T QtPrivate::QVariantValueHelper<T>:bject(const QVariant&) [with T = ByteArrayClass*]'
    /usr/include/qt5/QtCore/qvariant.h:101:37: required from 'static ReturnType QtPrivate::ObjectInvoker<Derived, Argument, ReturnType>::invoke(Argument) [with Derived = QtPrivate::QVariantValueHelper<ByteArrayClass*>; Argument = const QVariant&; ReturnType = ByteArrayClass*]'
    /usr/include/qt5/QtCore/qvariant.h:810:64: required from 'T qvariant_cast(const QVariant&) [with T = ByteArrayClass*]'
    /usr/include/qt5/QtScript/qscriptengine.h:349:50: required from 'T qscriptvalue_cast(const QScriptValue&) [with T = ByteArrayClass*]'
    ../customClass/bytearrayclass.cpp:157:82: required from here
    /usr/include/qt5/QtCore/qglobal.h:679:85: error: invalid application of 'sizeof' to incomplete type 'QStaticAssertFailure<false>'
    enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_resu lt, __COUNTER__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
    ^
    /usr/include/qt5/QtCore/qglobal.h:684:47: note: in expansion of macro 'Q_STATIC_ASSERT'
    #define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
    ^
    /usr/include/qt5/QtCore/qobject.h:520:5: note: in expansion of macro 'Q_STATIC_ASSERT_X'
    Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<Obj Type>::Value,
    ^
    make: *** [bytearrayclass.o] Error 1
    2) Experiment 1:
    Qt Code:
    1. qScriptRegisterQObjectMetaType<myObject*>(&engine);
    2. QScriptValue myObjectClass = engine.scriptValueFromQMetaObject<myObject>();
    3. engine.globalObject().setProperty("myObject", myObjectClass);
    4.  
    5. QScriptValue result = engine.evaluate("var obj = new myObject();");
    6. // (program crashes according to GDB at (??))
    To copy to clipboard, switch view to plain text mode 

    3) Experiment 2:
    Qt Code:
    1. QScriptEngine engine;
    2. myCLassPrototype myProto;
    3. engine.setDefaultPrototype(qMetaTypeId<myClassMaster*>(),
    4. engine.newQObject(&myProto));
    5. engine.evaluate("var x = new myClassProto()");
    6. // or engine.evaluate("var x = new myClassMaster()");
    7. // (resulting in "ReferenceError: Can't find variable: shitCLassPrototype")
    To copy to clipboard, switch view to plain text mode 

    4) Experiment 3:
    Qt Code:
    1. class Wrapper_QMessageBox: public QMessageBox, protected QScriptable
    2. {
    3. Q_OBJECT
    4. public:
    5.  
    6. Wrapper_QMessageBox(QWidget *parent =0)
    7. : QMessageBox(parent) {}
    8.  
    9. Wrapper_QMessageBox(Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint)
    10. : QMessageBox(icon,title,text,buttons,parent,f) {}
    11.  
    12. public slots:
    13. QScriptValue qscript_call(QWidget *parent = 0)
    14. {
    15. QMessageBox * const iface = new Wrapper_QMessageBox(parent);
    16. return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
    17. }
    18. QScriptValue qscript_call( Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint )
    19. {
    20. QMessageBox * const iface = new Wrapper_QMessageBox(icon,title,text,buttons,parent,f);
    21. return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
    22. }
    23. void setWindowTitle ( const QString & title )
    24. {
    25. QMessageBox::setWindowTitle(title);
    26. }
    27. };
    28.  
    29. engine.globalObject().setProperty("QMessageBox", engine.newQObject(new Wrapper_QMessageBox, QScriptEngine::AutoOwnership));
    30. QScriptValue result = engine.evaluate("var x = new QMessageBox();");
    31. // (resulting in "error: TypeError: Result of expression 'QMessageBox' [Wrapper_QMessageBox(name = "")] is not a constructor.<global>() at 1")
    To copy to clipboard, switch view to plain text mode 

    Also, whenever i've tried to use:
    Qt Code:
    1. Q_SCRIPT_DECLARE_QMETAOBJECT(myObject, QObject*);
    To copy to clipboard, switch view to plain text mode 
    or
    Qt Code:
    1. Q_DECLARE_METATYPE(myObject);
    To copy to clipboard, switch view to plain text mode 

    gcc yells at me that:
    In file included from ../../Qt5.3.1/5.3/gcc_64/include/QtScript/QScriptEngine:1:0,
    from ../scriptedObjects/main.cpp:2:
    ../scriptedObjects/main.cpp: In function 'void testsuite3::startTest()':
    ../../Qt5.3.1/5.3/gcc_64/include/QtScript/qscriptengine.h:281:1: error: a template declaration cannot appear at block scope
    template<> inline QScriptValue qscriptQMetaObjectConstructor<T>(QScriptContext *ctx, QScriptEngine *eng, T *) \
    ^
    ../scriptedObjects/main.cpp:93:9: note: in expansion of macro 'Q_SCRIPT_DECLARE_QMETAOBJECT'
    Q_SCRIPT_DECLARE_QMETAOBJECT(myObject, QObject*);
    ^
    make: *** [main.o] Error 1
    Besides: where are all the QtScript examples in the Qt 5.3 SDK (QtCreator doesn't show any - only QML examples when searching for "script")?

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to really really use custom QtScript classes

    I would go for the method of providing a constructor function
    http://qt-project.org/doc/qt-5/qscri...newQMetaObject

    Basically you have a stand-alone C++ function that can create an object of your type and then registers that instance with the engine using newQObject().

    This function, wrapped in a QScriptValue by newFunction(), is then registered as a constructor for you class's meta object.

    Qt Code:
    1. QScriptValue myClassConstructor(QScriptContext *context, QScriptEngine *engine)
    2. {
    3. QObject *object = new MyClass();
    4. return engine->newQObject(object, QScriptEngine::ScriptOwnership);
    5. }
    6.  
    7. ...
    8.  
    9. QScriptValue ctor = engine.newFunction(myClassConstructor);
    10. QScriptValue metaObject = engine.newQMetaObject(&MyClass::staticMetaObject, ctor);
    11. engine.globalObject().setProperty("MyClass", metaObject);
    12.  
    13. QScriptValue result = engine.evaluate("new MyClass()");
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  3. #3
    Join Date
    Apr 2012
    Location
    Vienna, Austria
    Posts
    17
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: How to really really use custom QtScript classes

    AWESOME - THANK YOU VERY MUCH, anda_skoa!

    Here is a working (~minimal) example, for whom ever googles about this.

    Have a nice weekend!

    main.cpp
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QScriptEngine>
    3. #include <QScriptContext>
    4. #include <QScriptValue>
    5. #include <QDebug>
    6.  
    7. #include "myClass.h"
    8.  
    9. QScriptValue myClassConstructor(QScriptContext* context, QScriptEngine* engine) {
    10. Q_UNUSED(context)
    11. QObject *object = new myClass();
    12. return engine->newQObject(object, QScriptEngine::ScriptOwnership);
    13. }
    14.  
    15. QScriptProgram evaluateMe("var x = new myClass();"
    16. "var y = new myClass();"
    17. ""
    18. "x.mySignal.connect(y.mySlot);"
    19. ""
    20. "x.setScriptValue('wooohoooo');"
    21. ""
    22. "y.setScriptValue(x.scriptValue());"
    23. ""
    24. // RESULTING:
    25. "y.scriptValue()",
    26. "main-script");
    27.  
    28. int main(int argc, char *argv[])
    29. {
    30. QCoreApplication a(argc, argv);
    31.  
    32. QScriptEngine engine;
    33. QScriptValue constructor = engine.newFunction(myClassConstructor);
    34. QScriptValue metaObject = engine.newQMetaObject(&myClass::staticMetaObject, constructor);
    35. engine.globalObject().setProperty("myClass", metaObject);
    36.  
    37. QScriptValue result = "result: " + engine.evaluate(evaluateMe).toString();
    38.  
    39. if (engine.hasUncaughtException()) {
    40. result = "error: " + engine.uncaughtException().toString() + ", " + engine.uncaughtExceptionBacktrace().join("\n");
    41. }
    42.  
    43. qDebug() << result.toString();
    44.  
    45. return a.exec();
    46. }
    To copy to clipboard, switch view to plain text mode 

    myclass.h
    Qt Code:
    1. #ifndef MYCLASS_H
    2. #define MYCLASS_H
    3.  
    4. #include <QObject>
    5. #include <QString>
    6. #include <QVariant>
    7. #include <QScriptValue>
    8. #include <QDebug>
    9.  
    10. class myClass : public QObject {
    11. Q_OBJECT
    12.  
    13. QScriptValue _secretScriptValue;
    14. public:
    15. myClass() {
    16. _secretScriptValue = QScriptValue("fresh and hot");
    17. }
    18.  
    19. public slots:
    20.  
    21. void setScriptValue(QScriptValue newValue) {
    22. _secretScriptValue = newValue;
    23. emit this->mySignal();
    24. }
    25.  
    26. QScriptValue scriptValue() {
    27. return _secretScriptValue;
    28. }
    29.  
    30. void mySlot() {
    31. qDebug() << "mySlot has been called! :)";
    32. }
    33.  
    34. signals:
    35. void mySignal();
    36. };
    37.  
    38. #endif // MYCLASS_H
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 2
    Last Post: 18th June 2013, 10:31
  2. Custom object usage inside QtScript
    By FuturePrimitive in forum Qt Programming
    Replies: 1
    Last Post: 6th September 2012, 06:40
  3. Using Qt classes in QtScript
    By totem in forum Qt Programming
    Replies: 4
    Last Post: 9th March 2011, 11:56
  4. QtScript: Iterate over all custom QScriptValues
    By android_ in forum Qt Programming
    Replies: 1
    Last Post: 25th October 2010, 11:20
  5. QWebView custom JS Classes?
    By ts230 in forum Qt Programming
    Replies: 0
    Last Post: 7th April 2010, 05:17

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.