Qt-interest Archive, November 2007
QtScript: PropertyGetter not working at first within prototypes
Message 1 in thread
This issue was found in Qt 4.3.2
Defining a prototype function with PropertyGetter and PropertySetter, the
PropertyGetter will not work when called first. After calling the
PropertySetter, the PropertyGetter will afterwords start working. Below you
find a minimal testcase.
// *** main.cpp:
#include <QCoreApplication>
#include <QScriptEngine>
#include "dir.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QScriptEngine e;
DirPrototype::initialize(&e);
e.evaluate(
"print('Dir.current:'); \n"
"print( Dir.current ); \n"
"print();"
"print('Dir.current = Z:/Projekte:'); \n"
"Dir.current = 'Z:/Projekte'; \n"
"print();"
"print('Dir.current:'); \n"
"print( Dir.current ); \n"
);
}
// *** Dir.h:
#ifndef DIR_H
#define DIR_H
#include <QObject>
#include <QDir>
#include <QScriptable>
class Dir : public QObject, public QDir
{
Q_OBJECT
public:
Dir(const QString& path, QObject* parent = 0) : QDir(path),
QObject(parent) {};
};
class DirPrototype : public QObject, protected QScriptable
{
Q_OBJECT
public:
DirPrototype(QObject* parent = 0) : QObject(parent) {};
static void initialize(QScriptEngine* engine);
};
#endif
// *** Dir.cpp:
#include "dir.h"
#include <QScriptEngine>
Q_DECLARE_METATYPE(Dir*)
static QScriptValue c_Dir(QScriptContext* context, QScriptEngine* engine)
{
QString path;
if (context->argumentCount() == 1)
path = context->argument(0).toString();
return engine->newQObject(new Dir(path),
QScriptEngine::ScriptOwnership);
}
static QScriptValue p_current(QScriptContext* context, QScriptEngine*
engine)
{
if (context->argumentCount() == 1) {
QString dir(context->argument(0).toString());
QDir::setCurrent(dir);
} // if
return engine->toScriptValue(QDir::currentPath());
}
void DirPrototype::initialize(QScriptEngine* engine)
{
// setup default prototype
DirPrototype *protoObject = new DirPrototype;
QScriptValue proto = engine->newQObject(protoObject,
QScriptEngine::ScriptOwnership);
engine->setDefaultPrototype(qMetaTypeId<Dir*>(), proto);
// setup constructor
QScriptValue ctor = engine->newFunction(c_Dir);
// static properties
ctor.setProperty(
"current",
engine->newFunction(p_current,
QScriptValue::PropertyGetter | QScriptValue::PropertySetter)
);
engine->globalObject().setProperty("Dir", ctor);
}
// *** Output when running:
Dir.current:
function () { [native] }
Dir.current = Z:/Projekte:
Dir.current:
Z:/Projekte
Regards, Seneca
Message 2 in thread
Acenes skrev:
>
> This issue was found in Qt 4.3.2
>
>
>
> Defining a prototype function with PropertyGetter and PropertySetter,
> the PropertyGetter will not work when called first. After calling the
> PropertySetter, the PropertyGetter will afterwords start working.
> Below you find a minimal testcase.
>
[...]
>
> ctor.setProperty(
>
> "current",
>
> engine->newFunction(p_current,
> QScriptValue::PropertyGetter | QScriptValue::PropertySetter)
>
> );
>
Hi,
Getter|setter flags are attributes of the property, not of the
associated function object. Specifically, the property flags should be
passed as the third argument to setProperty(), not to newFunction(); you
are passing the flags as the length argument in the newFunction() call,
so the only thing accomplished is to create a function with length=24. :-)
And no, the property getter does not "start working" when you assign to
the property; what you are doing when assigning the value is to
overwrite your function object (since the property was _not_ defined
with getter|setter attributes), so when you're subsequently reading the
property you're simply getting back the value you assigned to it (a
qDebug() in the getter|setter function would reveal that it's never called).
Regards,
Kent
--
[ signature omitted ]
Message 3 in thread
Kent, thanks for pointing out my mistake.
Now it works perfectly.
--
[ signature omitted ]