Hello everybody 
i'm aiming for the following ecma scenario:
var whatever = new myClass();
whatever.whatreallyever();
var whatever = new myClass();
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
ByteArrayClass *cls = qscriptvalue_cast<ByteArrayClass*>(ctx->callee().data());
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:
qScriptRegisterQObjectMetaType<myObject*>(&engine);
QScriptValue myObjectClass = engine.scriptValueFromQMetaObject<myObject>();
engine.globalObject().setProperty("myObject", myObjectClass);
QScriptValue result = engine.evaluate("var obj = new myObject();");
// (program crashes according to GDB at (??))
qScriptRegisterQObjectMetaType<myObject*>(&engine);
QScriptValue myObjectClass = engine.scriptValueFromQMetaObject<myObject>();
engine.globalObject().setProperty("myObject", myObjectClass);
QScriptValue result = engine.evaluate("var obj = new myObject();");
// (program crashes according to GDB at (??))
To copy to clipboard, switch view to plain text mode
3) Experiment 2:
QScriptEngine engine;
myCLassPrototype myProto;
engine.setDefaultPrototype(qMetaTypeId<myClassMaster*>(),
engine.newQObject(&myProto));
engine.evaluate("var x = new myClassProto()");
// or engine.evaluate("var x = new myClassMaster()");
// (resulting in "ReferenceError: Can't find variable: shitCLassPrototype")
QScriptEngine engine;
myCLassPrototype myProto;
engine.setDefaultPrototype(qMetaTypeId<myClassMaster*>(),
engine.newQObject(&myProto));
engine.evaluate("var x = new myClassProto()");
// or engine.evaluate("var x = new myClassMaster()");
// (resulting in "ReferenceError: Can't find variable: shitCLassPrototype")
To copy to clipboard, switch view to plain text mode
4) Experiment 3:
class Wrapper_QMessageBox
: public QMessageBox,
protected QScriptable
{
Q_OBJECT
public:
Wrapper_QMessageBox
(QWidget *parent
=0)
Wrapper_QMessageBox
(Icon icon,
const QString & title,
const QString & text, StandardButtons buttons
= NoButton,
QWidget * parent
= 0, Qt
::WindowFlags f
= Qt
::Dialog | Qt
::MSWindowsFixedSizeDialogHint)
public slots:
QScriptValue qscript_call
(QWidget *parent
= 0) {
QMessageBox * const iface
= new Wrapper_QMessageBox
(parent
);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
QScriptValue qscript_call
( Icon icon,
const QString & title,
const QString & text, StandardButtons buttons
= NoButton,
QWidget * parent
= 0, Qt
::WindowFlags f
= Qt
::Dialog | Qt
::MSWindowsFixedSizeDialogHint ) {
QMessageBox * const iface
= new Wrapper_QMessageBox
(icon,title,text,buttons,parent,f
);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
void setWindowTitle
( const QString & title
) {
}
};
engine.globalObject().setProperty("QMessageBox", engine.newQObject(new Wrapper_QMessageBox, QScriptEngine::AutoOwnership));
QScriptValue result = engine.evaluate("var x = new QMessageBox();");
// (resulting in "error: TypeError: Result of expression 'QMessageBox' [Wrapper_QMessageBox(name = "")] is not a constructor.<global>() at 1")
class Wrapper_QMessageBox: public QMessageBox, protected QScriptable
{
Q_OBJECT
public:
Wrapper_QMessageBox(QWidget *parent =0)
: QMessageBox(parent) {}
Wrapper_QMessageBox(Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint)
: QMessageBox(icon,title,text,buttons,parent,f) {}
public slots:
QScriptValue qscript_call(QWidget *parent = 0)
{
QMessageBox * const iface = new Wrapper_QMessageBox(parent);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
QScriptValue qscript_call( Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint )
{
QMessageBox * const iface = new Wrapper_QMessageBox(icon,title,text,buttons,parent,f);
return engine()->newQObject(iface, QScriptEngine::AutoOwnership);
}
void setWindowTitle ( const QString & title )
{
QMessageBox::setWindowTitle(title);
}
};
engine.globalObject().setProperty("QMessageBox", engine.newQObject(new Wrapper_QMessageBox, QScriptEngine::AutoOwnership));
QScriptValue result = engine.evaluate("var x = new QMessageBox();");
// (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:
Q_SCRIPT_DECLARE_QMETAOBJECT
(myObject,
QObject*);
Q_SCRIPT_DECLARE_QMETAOBJECT(myObject, QObject*);
To copy to clipboard, switch view to plain text mode
or
Q_DECLARE_METATYPE(myObject);
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")?
Bookmarks