Как получить Javascript в QWebView для создания новых экземпляров классов на основе C ++? - PullRequest
6 голосов
/ 03 июня 2009

Я успешно добавил объект C ++ в QWebFrame с помощью addToJavaScriptWindowObject , и может вызвать слот на этот объект из JavaScript.

Но я действительно хочу, чтобы один из этих слотов возвратил новый объект. Например, у меня есть слот, подобный этому, который возвращает экземпляр производного класса QObject:

   MyObject* MyApp::helloWorld()
   {
          //MyObject is dervied from QObject
          return new MyObject();
   }

Я могу успешно назвать этот слот из javascript следующим образом

   var foo=myapp.helloWorld();

Но foo кажется пустым, я не могу вызвать ни одного слота или получить доступ к любому свойства на него из Javascript.

Есть идеи, как мне этого достичь?

Ответы [ 5 ]

4 голосов
/ 04 июня 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 голосов
/ 03 июня 2011

Вы можете назначить указатель вашего объекта на QObject * и вернуть его.

    QObject * obj = new MyObject();
    return obj;

Это работает для меня на порте Qt Webkit в Linux.

1 голос
/ 11 июня 2009

Попробуйте вернуть ваш новый объект как QObject *, а не MyObject *. Если вы просто работаете с QtScript, то вы можете вызвать qScriptRegisterMetaType , чтобы определить некоторый код для обработки преобразования MyObject * s в QScriptValues ​​(или QVariants), но, похоже, нет эквивалента для Движок JavaScript, используемый в QtWebKit.

Досадно, это означает, что предоставление вашей внутренней объектной модели WebKit будет включать либо наличие отдельного набора прокси-функций, которые преобразуют ваши указатели объектов в QObject * s, либо использование каких-либо классов адаптеров для того же действия.

1 голос
/ 04 июня 2009

QtScript имеет понятие прототипов - что позволяет вам создавать прототип C ++ для значения скрипта. Мы исследуем, можем ли мы связать QtScript с JavaScriptCore - что должно привести к возможности использования прототипов из среды JavaScript WebKit; http://doc.trolltech.com/4.5/qtscript.html#making-use-of-prototype-based-inheritance

0 голосов
/ 05 октября 2015

Этот ответ основан на ответе Павла, но немного упрощен. Протестировано и работает на Qt 5.3. Вам нужна фабрика, которая создает экземпляр объекта, а затем возвращает указатель QObject на этот объект. Класс объекта должен наследоваться от QObject, чтобы он правильно работал в JavaScript:

QObject * MyApp::createInstance(QString objname) {
    MyClass * obj = new MyClass(this);
    m_mainWindow->webView->page()->mainFrame()->addToJavaScriptWindowObject(objname, obj, QWebFrame::ScriptOwnership);
    return obj;
}

С этим вы можете сделать следующее из 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

...