Как получить Javascript в QWebView для создания новых экземпляров классов на основе С++?
Автор вопроса: Paul DixonОтветов: 5
Я успешно добавил объект C++ в QWebFrame с помощью addToJavaScriptWindowObject, и может вызвать слот для этого объекта из javascript.
Но я действительно хочу, чтобы один из этих слотов возвращал новый объект. Например, у меня есть такой слот, который возвращает экземпляр производного класса QObject:
MyObject* MyApp::helloWorld()
{
//MyObject is dervied from QObject
return new MyObject();
}
Я могу успешно вызвать этот слот из javascript, как это
var foo=myapp.helloWorld();
Но foo кажется пустым, я не могу вызвать какие-либо слоты или получить доступ к каким-либо свойствам из Javascript.
Любые идеи о том, как я могу достичь этого?
В вопросе вы имеете в виду MyApp::helloWorld, верно? jrharshath 03.06.2009
Один довольно уродливый хак, который я рассматривал, состоит в том, чтобы использовать addToJavaScriptWindowObject для удаления объекта, который я хочу вернуть, в объект окна со случайным именем, а затем вместо этого мой слот возвращает имя экземпляра объекта:
QString MyApp::helloWorld()
{
//general a unique name for the js variable
QString name=getRandomVariableName();
//here's the object we want to expose to js
MyObject* pReturn=new MyObject();
//we make attach our object to the js window object
getWebFrame()->addToJavaScriptWindowObject(name, pReturn,
QScriptEngine::ScriptOwnership);
//tell js the name we used
return name;
}
JS можно написать, чтобы проверить, является ли возвращаемое значение строкой, и если это так, захватить объект из окна:
var foo=myapp.helloWorld();
if (typeof foo == "string")
{
foo=window[foo];
}
Немного некрасиво, но сойдет, пока не появится лучший метод. В будущих версиях Qt будет унифицирована поддержка сценариев, так что все будет основано на JavaScriptCore в WebKit, так что, надеюсь, тогда это улучшится!
Ответ 2 · рейтинг 2 · Chandan
Вы можете назначить указатель объекта на QObject * и вернуть его.
QObject * obj = new MyObject();
return obj;
Это работает для меня на порте Qt Webkit в Linux.
Ответ 3 · рейтинг 1 · Henrik Hartz
В QtScript есть понятие прототипов, которое позволяет вам создать прототип C++ для значения сценария. Мы изучаем, можем ли мы соединить QtScript с JavaScriptCore, что должно также привести к возможности использования прототипов из среды JavaScript WebKit; http://doc.trolltech.com/4.5/qtscript.html#making-use-of-prototype-based-inheritance
Ответ 4 · рейтинг 1 · Rob Knight
Попробуйте вернуть новый объект как QObject*, а не как MyObject*. Если вы просто работаете с QtScript, вы можете вызвать qScriptRegisterMetaType, чтобы определить некоторый код для обработки преобразования MyObject * в QScriptValues (или QVariants), но, похоже, не существует эквивалента для механизма JavaScript, используемого в QtWebKit.
Досадно, что это означает, что раскрытие вашей внутренней объектной модели для WebKit потребует либо наличия отдельного набора прокси-функций, которые преобразуют ваши указатели объектов в QObject*s, либо использования некоторых классов адаптеров для выполнения того же самого.
Ответ 5 · Michael Franzl
Этот ответ основан на ответе Пола, но немного упрощен. Протестировано и работает для Qt 5.3. Вам нужна фабрика, которая создает экземпляр объекта, а затем возвращает указатель QObject на этот объект. Класс объекта должен наследоваться от QObject, чтобы он правильно работал в JavaScript:
При этом вы можете сделать следующее из Javascript:
var myobject = MyApp.createInstance("obj1");
На данный момент у вас есть obj1, а также myobject в глобальном пространстве имен JavaScript (это просто указатели, поэтому выполняются обе следующие работы:
myobject.testmethod();
obj1.testmethod();
На этом этапе вы можете использовать connect в JavaScript для подключения сигналов C++ к слотам JavaScript. Более подробная информация об этом методе здесь: http://doc.qt.io/qt-5/qtwebkit-bridge.html