Custom Script Class Parameterübergabe
Verfasst: 26. August 2013 11:31
Hallo allerseits,
dies ist mein erster Thread in dem Forum hier und damit seien erstmal alle gegrüßt.
Nun zu meinem kleinen Problem.
Ich möchte mir einige Klasse entwickeln, welche mithilfe der QScriptEngine verarbeitet und ausgeführt werden sollen.
Angefangen habe ich mit einer einfachen String-Klasse
ch weiß die String-Class ist schon von Haus aus eingebaut). Das funktioniert soweit auch schon ganz gut.
Hier der JavaScript-Code (funktioniert):
Dieser hier funktioniert nicht:
Der Unterschied der beiden Quelltexte ist nur, dass in Zeile 6 die Methode "getString()" von Objekt "string1" nicht mehr aufgerufen wird.
Es wird die Referenz auf das Objekt übergeben. Und genau dass scheint in meiner Implementierung zu fehlen oder fehlerhaft zu sein.
Die Ausführung des Skriptes wird jedenfalls an dieser Stelle abgebrochen.
Habe ich in der QdbStringScriptPrototype oder der QdbStringScriptClass-Klasse etwas übersehen?
Ich würde die "getString"-Methoden gerne vermeiden, da das Objekt selber ja den String repräsentiert.
Hier der C++ Source:
QdbString.h
QdbString.cpp
QdbStringScriptClass.h
QdbStringScriptClass.cpp
QdbStringScriptPrototype.h
QdbStringScriptPrototype.cpp
Ich bedanke mich im Voraus für die Hilfe!
Gruß
Manuel
dies ist mein erster Thread in dem Forum hier und damit seien erstmal alle gegrüßt.
Nun zu meinem kleinen Problem.
Ich möchte mir einige Klasse entwickeln, welche mithilfe der QScriptEngine verarbeitet und ausgeführt werden sollen.
Angefangen habe ich mit einer einfachen String-Klasse
Hier der JavaScript-Code (funktioniert):
Code: Alles auswählen
var string1 = new QdbString();
var string2 = new QdbString();
var msgBox = new QdbMessageBox();
string1.assign("Hallo Welt!");
string2.assign(string1.getString());
msgBox.setTitle(string1.getString());
msgBox.setText(string2.getString());
msgBox.exec();Code: Alles auswählen
var string1 = new QdbString();
var string2 = new QdbString();
var msgBox = new QdbMessageBox();
string1.assign("Hallo Welt!");
string2.assign(string1);
msgBox.setTitle(string1.getString());
msgBox.setText(string2.getString());
msgBox.exec();Es wird die Referenz auf das Objekt übergeben. Und genau dass scheint in meiner Implementierung zu fehlen oder fehlerhaft zu sein.
Die Ausführung des Skriptes wird jedenfalls an dieser Stelle abgebrochen.
Habe ich in der QdbStringScriptPrototype oder der QdbStringScriptClass-Klasse etwas übersehen?
Ich würde die "getString"-Methoden gerne vermeiden, da das Objekt selber ja den String repräsentiert.
Hier der C++ Source:
QdbString.h
Code: Alles auswählen
#ifndef QDBSTRING_H
#define QDBSTRING_H
// Qt includes
#include <QObject>
#include <QString>
// Class
class QdbString : public QObject
{
Q_OBJECT
private:
// private: fields
QString m_String;
public:
// public: methods (constructors)
explicit QdbString(QObject *parent = 0);
QdbString(const QdbString &_Object);
public Q_SLOTS:
// public: methods
void assign(const char* _String);
void assign(const QString &_String);
void assign(const QdbString &_String);
bool isEqual(const char* _String) const;
bool isEqual(const QString& _String) const;
bool isEqual(const QdbString& _String) const;
public Q_SLOTS:
// public: methods (getters)
QString toQString() const;
public:
// public: methods (operators)
QdbString& operator =(const QdbString &_Object);
bool operator ==(const QdbString &_Object) const;
};
#endif // QDBSTRING_H
Code: Alles auswählen
#include "QdbString.h"
QdbString::QdbString(QObject *parent) :
QObject(parent)
{
}
QdbString::QdbString(const QdbString &_Object)
{
this->assign(_Object);
}
// public: methods
void QdbString::assign(const char* _String)
{
this->m_String = _String;
}
void QdbString::assign(const QString &_String)
{
this->m_String = _String;
}
void QdbString::assign(const QdbString &_String)
{
this->m_String = _String.m_String;
}
bool QdbString::isEqual(const char* _String) const
{
if(this->m_String == _String)
return true;
return false;
}
bool QdbString::isEqual(const QString& _String) const
{
if(this->m_String == _String)
return true;
return false;
}
bool QdbString::isEqual(const QdbString& _String) const
{
if(this->m_String == _String.m_String)
return true;
return false;
}
// public: methods (getters)
QString QdbString::toQString() const
{
return this->m_String;
}
// public: methods (operators)
QdbString& QdbString::operator =(const QdbString &_Object)
{
this->assign(_Object);
return *this;
}
bool QdbString::operator ==(const QdbString &_Object) const
{
return this->isEqual(_Object);
}
Code: Alles auswählen
#ifndef QDBSTRINGSCRIPTCLASS_H
#define QDBSTRINGSCRIPTCLASS_H
// Qt includes
#include <QtCore/QObject>
#include <QtScript/QScriptContext>
#include <QtScript/QScriptClass>
#include <QtScript/QScriptString>
// Project includes
#include "QdbString.h"
// Class
class QdbStringScriptClass : public QObject, public QScriptClass
{
Q_OBJECT
private:
// private: fields
QScriptValue m_Prototype;
QScriptValue m_Constructor;
public:
// public: methods (constructors)
explicit QdbStringScriptClass(QScriptEngine *_ScriptEngine);
// public: methods (destructor)
virtual ~QdbStringScriptClass();
private:
// private: methods (static)
static QScriptValue construct(QScriptContext *ctx, QScriptEngine *eng);
static QScriptValue toScriptValue(QScriptEngine *_ScriptEngine, const QdbString &_Object);
static void fromScriptValue(const QScriptValue &_ScriptValue, QdbString &_Object);
public:
// public: methods
QScriptValue constructor();
QScriptValue newInstance();
QScriptValue newInstance(const QdbString &_Object);
QueryFlags queryProperty(const QScriptValue &_Object, const QScriptString &_Name, QueryFlags _Flags, uint *_Id);
QScriptValue property(const QScriptValue &_Object, const QScriptString &_Name, uint _Id);
QScriptValue::PropertyFlags propertyFlags(const QScriptValue &_Object, const QScriptString &_Name, uint _Id);
QString name() const;
QScriptValue prototype() const;
public:
// public: methods (setters)
void setProperty(QScriptValue &_Object, const QScriptString &_Name, uint _Id, const QScriptValue &_Value);
};
#endif // QDBSTRINGSCRIPTCLASS_H
Code: Alles auswählen
// Qt includes
#include <QtScript/QScriptContext>
#include <QtScript/QScriptEngine>
// Project includes
#include "QdbStringScriptClass.h"
#include "QdbStringScriptPrototype.h"
// Declare metatypes
Q_DECLARE_METATYPE(QdbString)
Q_DECLARE_METATYPE(QdbString*)
Q_DECLARE_METATYPE(QdbStringScriptClass*)
// public: methods (constructors)
QdbStringScriptClass::QdbStringScriptClass(QScriptEngine *_ScriptEngine) :
QObject(_ScriptEngine),
QScriptClass(_ScriptEngine)
{
// fields
QScriptValue global;
qScriptRegisterMetaType<QdbString>(_ScriptEngine, toScriptValue, fromScriptValue);
this->m_Prototype = _ScriptEngine->newQObject(
new QdbStringScriptPrototype(this),
QScriptEngine::QtOwnership,
QScriptEngine::SkipMethodsInEnumeration |
QScriptEngine::ExcludeSuperClassMethods |
QScriptEngine::ExcludeSuperClassProperties
);
global = _ScriptEngine->globalObject();
this->m_Prototype.setPrototype(global.property("Object").property("prototype"));
this->m_Constructor = _ScriptEngine->newFunction(construct, this->m_Prototype);
this->m_Constructor.setData(_ScriptEngine->toScriptValue(this));
}
// public: methods (destructor)
QdbStringScriptClass::~QdbStringScriptClass() {
}
// private: methods (static)
QScriptValue QdbStringScriptClass::construct(QScriptContext *ctx, QScriptEngine *eng)
{
QdbStringScriptClass *cls = qscriptvalue_cast<QdbStringScriptClass*>(ctx->callee().data());
if(!cls)
return QScriptValue();
QScriptValue arg = ctx->argument(0);
if(arg.instanceOf(ctx->callee()))
return cls->newInstance(qscriptvalue_cast<QdbString>(arg));
return cls->newInstance();
}
QScriptValue QdbStringScriptClass::toScriptValue(QScriptEngine *_ScriptEngine, const QdbString &_Object)
{
// fields
QScriptValue constructor = _ScriptEngine->globalObject().property("QdbString");
QdbStringScriptClass *cls = qscriptvalue_cast<QdbStringScriptClass*>(constructor.data());
if (!cls)
return _ScriptEngine->newVariant(QVariant::fromValue(_Object));
return cls->newInstance(_Object);
}
void QdbStringScriptClass::fromScriptValue(const QScriptValue &_ScriptValue, QdbString &_Object)
{
_Object = qvariant_cast<QdbString>(_ScriptValue.data().toVariant());
}
// public: methods
QScriptValue QdbStringScriptClass::constructor()
{
return m_Constructor;
}
QScriptValue QdbStringScriptClass::newInstance()
{
return newInstance(QdbString());
}
QScriptValue QdbStringScriptClass::newInstance(const QdbString &_Object)
{
QScriptValue data = this->engine()->newVariant(QVariant::fromValue(_Object));
return this->engine()->newObject(this, data);
}
QScriptClass::QueryFlags QdbStringScriptClass::queryProperty(const QScriptValue &_Object, const QScriptString &_Name, QueryFlags _Flags, uint *_Id)
{
QdbString *object = qscriptvalue_cast<QdbString*>(_Object.data());
bool isArrayIndex = false;
if(!object)
return 0;
if(!isArrayIndex)
return 0;
return _Flags;
}
QScriptValue QdbStringScriptClass::property(const QScriptValue &_Object, const QScriptString &_Name, uint _Id)
{
// fields
QdbString *object = qscriptvalue_cast<QdbString*>(_Object.data());
if(!object)
return QScriptValue();
return QScriptValue();
}
QScriptValue::PropertyFlags QdbStringScriptClass::propertyFlags(const QScriptValue &_Object, const QScriptString &_Name, uint _Id)
{
return QScriptValue::Undeletable;
}
QString QdbStringScriptClass::name() const
{
return QLatin1String("QdbString");
}
QScriptValue QdbStringScriptClass::prototype() const
{
return m_Prototype;
}
// public: methods (setters)
void QdbStringScriptClass::setProperty(QScriptValue &_Object, const QScriptString &_Name, uint _Id, const QScriptValue &_Value)
{
// fields
QdbString *object = qscriptvalue_cast<QdbString*>(_Object.data());
//
if(!object)
return;
}
Code: Alles auswählen
#ifndef QDBSTRINGSCRIPTPROTOTYPE_H
#define QDBSTRINGSCRIPTPROTOTYPE_H
// Qt includes
#include <QObject>
#include <QtScript/QScriptable>
#include <QtScript/QScriptValue>
// Project includes
#include "QdbString.h"
// Class
class QdbStringScriptPrototype : public QObject, public QScriptable
{
Q_OBJECT
public:
// public: methods (constructors)
explicit QdbStringScriptPrototype(QObject *parent = 0);
// public: methods (destructor)
virtual ~QdbStringScriptPrototype();
private:
// private: methods
QScriptValue valueOf() const;
QdbString* nativeObject() const;
public Q_SLOTS:
// public: methods
void assign(const char* _String);
void assign(const QString& _String);
void assign(const QdbString& _String);
public Q_SLOTS:
// public: methods (setters)
public Q_SLOTS:
// public: methods (getters)
QScriptValue getString() const;
};
#endif // QDBSTRINGSCRIPTPROTOTYPE_H
Code: Alles auswählen
// Qt includes
#include <QtScript/QScriptEngine>
// Project includes
#include "QdbStringScriptPrototype.h"
// Declare as metatype
Q_DECLARE_METATYPE(QdbString*)
// public: methods (constructors)
QdbStringScriptPrototype::QdbStringScriptPrototype(QObject *parent) :
QObject(parent)
{
}
// public: methods (destructor)
QdbStringScriptPrototype::~QdbStringScriptPrototype()
{
}
// private: methods
QScriptValue QdbStringScriptPrototype::valueOf() const
{
return this->thisObject().data();
}
QdbString* QdbStringScriptPrototype::nativeObject() const
{
return qscriptvalue_cast<QdbString*>(this->thisObject().data());
}
// public: methods
void QdbStringScriptPrototype::assign(const char* _String) {
this->nativeObject()->assign(_String);
}
void QdbStringScriptPrototype::assign(const QString& _String)
{
this->nativeObject()->assign(_String);
}
void QdbStringScriptPrototype::assign(const QdbString &_String)
{
this->nativeObject()->assign(_String);
}
// public: methods (setters)
// public: methods (getters)
QScriptValue QdbStringScriptPrototype::getString() const
{
return this->nativeObject()->toQString();
}
Gruß
Manuel