Можно ли сделать QObject вызываемым из Java Script

Можно ли сделать QObject вызываемым из Java Script? Я имею в виду регистрацию экземпляра производного класса QObject следующим образом:

QObject* obj = new MyObject();
QJSValue js_value = js_engine.newQObject(obj);

js_engine.globalObject().setProperty("myFunction", js_value);

а затем иметь возможность вызывать myFunction из Java Script

myFunction()

Среда: Qt 5.0.1

Редактировать: Основная цель этой манипуляции - зарегистрировать функцию C++ или функтор в движке Java Script и сделать его доступным не как свойство объекта, а как отдельную функцию.


person MaksymB    schedule 28.02.2013    source источник
comment
Что вы имеете в виду под make QObject callable? Сделать его функции-члены доступными? Основываясь на вашем списке тегов: вы пытаетесь получить доступ к одному из ваших объектов C++ из JavaScript внутри привязок свойств QML?   -  person axxel    schedule 28.02.2013
comment
возможный дубликат stackoverflow.com/questions/943554/   -  person Min Lin    schedule 01.03.2013
comment
И Qt предоставляет хороший пример: apidocs.meego.com/1.2/qt4/webkit -imageanalyzer.html   -  person Min Lin    schedule 01.03.2013
comment
axxel, под callable я подразумеваю, когда QJSValue::isCallable() возвращает true. В свою очередь это означает, что объект можно вызывать из JS. Не только один из его методов, но и сам объект.   -  person MaksymB    schedule 01.03.2013
comment
Мин Лин, нет, это не то же самое.   -  person MaksymB    schedule 01.03.2013
comment
@Maxym, можешь показать пример на C++, как ты хочешь вызвать сам obj?   -  person Alexander Stepaniuk    schedule 02.03.2013
comment
@ Александр Степанюк, я хочу вызвать его из Java Script, а не из C++. Но в C++ это будет выглядеть как js_value.call(..).   -  person MaksymB    schedule 03.03.2013
comment
@Maxym, объект C++ нельзя назвать самим собой. Ни в C++, ни в JS. Можно вызвать метод. Мне кажется, вы хотите вызвать какой-то метод класса obj. Как уже упоминал Аксель.   -  person Alexander Stepaniuk    schedule 03.03.2013
comment
@Александр Степанюк, ок, я тоже не нашел как это сделать. Я сомневался, что это невозможно, потому что тогда мне как бы невозможно экспортировать одну функцию (или функтор) из C++ в Java Script только объект с методами.   -  person MaksymB    schedule 04.03.2013


Ответы (3)


Я потратил слишком много времени, пытаясь сделать то же самое. И теперь я на 99,9% уверен, что с текущей сборкой Qt (5.0.1) это сделать невозможно.

person Alexandr    schedule 01.04.2013
comment
хорошо, выглядит так. Спасибо! Отрицательный ответ - это тоже ответ. - person MaksymB; 01.04.2013

Я не думаю, что можно добавить функцию в глобальный объект QJSEngine непосредственно из C++. Хотя этот трюк работает:

  1. Определите класс на основе QObject с функциями Q_INVOKABLE, которые вы хотите предоставить QJSEngine.

    class MyObject : public QObject 
    {
        Q_OBJECT
    public:
        Q_INVOKABLE int myFunction(int x) 
        {
            return x + 3;
        }
    };
    
  2. Создайте экземпляр этого объекта и определите его родителя из C++. (Важно, чтобы вы определили родителя для своего экземпляра объекта. Без родителя QJSEngine будет думать, что он владеет объектом, и может удалить его!)

    MyObject *obj = new MyObject();
    obj->setParent(QCoreApplication::instance());
    
  3. Предоставьте свой объект QJSEngine.

    js_engine.globalObject().setProperty("myObject", js_engine.newQObject(obj));
    
  4. Перенесите функции вашего объекта в глобальный объект из JavaScript.

     engine.evaluate("this.myFunction = myObject.myFunction");
    
  5. Удалите myObject из среды JavaScript.

     engine.evaluate("delete myObject");
    

Готово!

person Jonathan    schedule 29.01.2016

Если вы используете Qt5, вы можете использовать:

QObject* obj = new MyObject();
js_engine.globalObject().setProperty("myFunction", js_engine.toScriptValue(&obj::myFunction));

И вам нужно, чтобы ваш класс, производный от QObject, имел макрос Q_OBJECT и Q_INVOKABLE для каждого метода, который должен быть представлен.

Если вы используете QML, вам лучше использовать QQmlContext::setContextObject :

youQmlContext.setContextObject(new MyObject());

Таким образом, все члены Q_PROPERTY, Q_INVOKABLE и Q_SLOT класса MyObject будут доступны для механизма QML/JS как члены самого контекста.

person TheBootroo    schedule 27.03.2013
comment
Что такое &obj::myFunction? 'obj' - это указатель. Это компилируется? - person MaksymB; 28.03.2013
comment
все же, что вы имеете в виду под этим? адрес функции-члена? тогда я не понимаю, на каком объекте он будет вызываться. - person MaksymB; 29.03.2013
comment
забудьте об этом, я думал, что мы можем зарегистрировать функцию-член из класса в JsEngine, но только Qml Engine позволяет это. - person TheBootroo; 29.03.2013