Всем привет.
Хочу, чтобы из скрипта были доступны свойства моего объекта вот так:
Javascript
module.frequency(1) = 15;
var a = module.frequency(2);
В строке module.frequency(1) = 15; должно быть не присвоение 15 переменной, ссылку на которую вернет module.frequency(1),
а фактически вызов функции frequency c 2-мя параметрами: 1 - индекс, 2 - значение.
(В функции frequency я пишу число 15 по Modbus в регистр с индексом 1).
Почти то, что нужно описывается в документации
http://qt-project.org/doc/qt-5.0/qtscript/qtscript-index.html#property-getters-and-settersProperty Getters and Setters
A script object property can be defined in terms of a getter/setter function, similar to how a Qt C++ property has read and write functions associated with it. This makes it possible for a script to use expressions like object.x instead of object.getX(); the getter/setter function for x will implicitly be invoked whenever the property is accessed. To scripts, the property looks and behaves just like a regular object property.
A single Qt Script function can act as both getter and setter for a property. When it is called as a getter, the argument count is 0. When it is called as a setter, the argument count is 1; the argument is the new value of the property. In the following example, we define a native combined getter/setter that transforms the value slightly:
QScriptValue getSet(QScriptContext *ctx, QScriptEngine *eng)
{
QScriptValue obj = ctx->thisObject();
QScriptValue data = obj.data();
if (!data.isValid()) {
data = eng->newObject();
obj.setData(data);
}
QScriptValue result;
if (ctx->argumentCount() == 1) {
QString str = ctx->argument(0).toString();
str.replace("Roberta", "Ken");
result = str;
data.setProperty("x", result);
} else {
result = data.property("x");
}
return result;
}
Недостаток 1: эти функции не могут быть методами класса. Соответственно this недоступен.
Недостаток 2: эти функции нужно прокидывать в глобальный объект явно, а хочется, чтобы они были доступны через объект
C++ (Qt)
QScriptEngine eng;
QScriptValue obj = eng.newObject();
obj.setProperty("x", eng.newFunction(getSet), QScriptValue::PropertyGetter|QScriptValue::PropertySetter);
Подскажите, что делать? Можно, конечно, попить валерьянки, успокоиться
и оставить по 2-му варианту, но вдруг можно сделать красиво?
Что делал.Вариант 1.
Есть объект со свойствами (так по-русски properties?):
C++ (Qt)
class Module : public QObject
{
Q_OBJECT
Q_PROPERTY(quint32 frequency1 READ frequency1 WRITE setFrequency1)
Q_PROPERTY(quint32 frequency2 READ frequency2 WRITE setFrequency2)
...
Q_PROPERTY(quint32 frequency99 READ frequency99 WRITE setFrequency99)
private:
...
}
Javascript
module.frequency1 = 15;
var a = module.frequency2;
Недостатки: некрасиво, много писанины, много возможностей ошибиться.
Вариант 2.
Вместо свойств делаю вызываемые методы:
C++ (Qt)
class Module : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE quint32 frequency(quint8 index);
Q_INVOKABLE void setFrequency(quint8 index, quint32 value);
}
Javascript
module.setFrequency(1, 15);
var a = module.frequency(2);
Пока у меня реализован 2-й вариант.