Como chegar Javascript em um QWebView para criar novas instâncias de classes com base C ++?

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

Pergunta

Eu adicionei com sucesso um objeto C ++ a um QWebFrame com addToJavaScriptWindowObject , e pode chamar um slot nesse objeto de javascript.

Mas o que eu realmente quero fazer é ter um desses slots de retornar um novo objeto. Por exemplo, eu tenho um slot como este, que retorna um QObject derivado instância de classe:

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

Eu posso chamar esse slot de javascript com sucesso como esta

   var foo=myapp.helloWorld();

mas parece foo estar vazio, não pode chamar qualquer slots ou o acesso de qualquer Propriedades nele de JavaScript.

Algumas ideias sobre como eu posso conseguir isso?

Foi útil?

Solução

Um corte feio Eu considerei é usar addToJavaScriptWindowObject para soltar o objeto Quero voltar para o objeto janela com um nome aleatório, então tenho a minha abertura de retorno o nome da instância do objeto em vez disso:

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;
}

A JS pode ser escrito para verificar se o valor de retorno é uma string, e se for, pegue o objeto da janela:.

var foo=myapp.helloWorld();
if (typeof foo == "string")
{
    foo=window[foo];
}

Um pouco feio, mas vai ter me por até um método melhor vem junto. Futuras versões do Qt vão unificar os scripting apoio para que tudo é baseado no JavaScriptCore no WebKit, por isso espero que isso vai melhorar, então!

Outras dicas

Você pode atribuir o ponteiro de objeto para um QObject * e retornar isso.

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

Isso está funcionando para mim na porta Qt Webkit no Linux.

QtScript tem a noção de protótipos - que lhe permite criar um C ++ protótipo para um valor script. Estamos investigando wether podemos colmatar QtScript com JavaScriptCore - que deve resultado na possibilidade de usar protótipos de ambiente JavaScript do WebKit também; http://doc.trolltech.com/ 4,5 / qtscript.html # tornando-based-use-of-protótipo-herança

Tente devolver o novo objeto como um QObject * em vez de um MyObject *. Se você está apenas trabalhando com QtScript, então você pode chamar qScriptRegisterMetaType para definir algum código para lidar com conversão de MyObject * s em QScriptValues ??(ou QVariants), mas não parece ser um equivalente para o motor JavaScript utilizada em QtWebKit.

Irritantemente, isso significa que expor o seu modelo de objeto interno para WebKit deve envolver quer ter um conjunto separado de funções de proxy que convertem seus ponteiros de objeto para QObject * s, ou usando classes de adaptador de algum tipo para fazer a mesma coisa.

Esta resposta é baseada na resposta de Paulo, mas um pouco simplificado. Testado e funcionando para o Qt 5.3. Você precisa de uma fábrica que instancia um objeto e, em seguida, retorna um ponteiro QObject a este objeto. classe do objeto deve herdar a partir QObject para que ele funcione corretamente em JavaScript:

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

Com isso, você pode fazer o seguinte a partir de Javascript:

var myobject = MyApp.createInstance("obj1");

Neste ponto, você tem obj1, bem como myobject no espaço global JavaScript (eles são apenas ponteiros, assim fazendo ambas as seguintes obras:

myobject.testmethod();
obj1.testmethod();

Neste ponto, você pode usar connect em JavaScript para conectar sinais de C ++ para ranhuras JavaScript. Mais informações sobre esta técnica aqui: http://doc.qt.io/qt- 5 / QtWebKit-bridge.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top