Как получить Javascript в QWebView для создания новых экземпляров классов на основе C ++?

StackOverflow https://stackoverflow.com/questions/943554

Вопрос

Я успешно добавил объект C ++ в QWebFrame с addToJavaScriptWindowObject Добавить javascriptwindowobject, и может вызывать слот для этого объекта из javascript.

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

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

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

   var foo=myapp.helloWorld();

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

Есть какие-нибудь идеи о том, как я могу этого добиться?

Это было полезно?

Решение

Я рассмотрел один довольно уродливый хак: использовать 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, так что, надеюсь, тогда ситуация улучшится!

Другие советы

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

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

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

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

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

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

Этот ответ основан на ответе Пола, но немного упрощен.Протестировано и работает на 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top