2015-08-10 18 views
8

Utilizzo la struttura QT WebEngine per visualizzare pagine Web. Inserisco javascript in una pagina quando viene caricato e voglio consentire al javascript di accedere a un oggetto QT. Apparentemente, per fare ciò deve esistere un QWebChannel che stabilisce un po 'di IPC tra chromium (la javascript) e il resto del mio progetto C++/QT. Mi sono imbattuto nella funzione QWebEnginePage :: setWebChannel (canale QWebChannel *), tuttavia non riesco a trovare alcun esempio del suo utilizzo. La documentazione (http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel) indica che qt.webChannelTransport dovrebbe essere disponibile nel contesto javascript, ma non vedo dove sia stabilito in qwebchannel.js (https://github.com/qtproject/qtwebchannel/blob/dev/src/webchannel/qwebchannel.js). Ho visto gli esempi di WebChannel (http://doc.qt.io/qt-5/qtwebchannel-examples.html) e vorrei evitare i WebSockets se possibile.QT QWebEnginePage :: setWebChannel() oggetto di trasporto

Di seguito è come ho cercato di implementare il canale web.

Ogni volta che una pagina viene caricata ho stabilire un canale e iniettare il codice JavaScript in C++:

QWebChannel *channel = new QWebChannel(); 
channel->registerObject(QStringLiteral("jshelper"), helper); 

view->page()->runJavaScript(qwebjs); //this is qwebchannel.js 
view->page()->setWebChannel(channel); 
view->page()->runJavaScript(myfunction); //function that calls QT object (jshelper) 

in JavaScript:

new QWebChannel(qt.webChannelTransport, function(channel) { ... }); 

che si traduce nel canale non essere collegato correttamente (supponendo che questo sia dovuto a qt.webChannelTransport, come funzionava quando stavo usando WebSockets). È anche apprezzato qualsiasi suggerimento su esempi di QWebChannel impostato con QWebEnginePage in questo modo.

risposta

20

Risposta breve: aggiungere <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script> alla tua pagina html (prima di chiamare new QWebChannel ovviamente), e rimuovere la riga view->page()->runJavaScript(qwebjs); //this is qwebchannel.js dal codice C++.

Risposta lunga:

anch'io ho avuto un sacco di problemi a capire come utilizzare QWebChannel senza WebSockets correttamente - è riuscito a farlo funzionare dopo aver scavato in giro in Qt di codice e le mailing list 5.5 di origine (la documentazione è ancora carente). Si noti che funziona solo con the new Qt 5.5.

Ecco come utilizzare QWebChannel:

// file: MyWebEngineView.cpp, MyWebEngineView extends QWebEngineView 
QWebChannel *channel = new QWebChannel(page()); 

// set the web channel to be used by the page 
// see http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel 
page()->setWebChannel(channel); 

// register QObjects to be exposed to JavaScript 
channel->registerObject(QStringLiteral("jshelper"), helper); 

// now you can call page()->runJavaScript(...) etc 
// you DON'T need to call runJavaScript with qwebchannel.js, see the html file below 

// load your page 
load(url); 

E sul lato JS:

<!-- NOTE: this is what you're missing --> 
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script> 

<script type="text/javascript"> 
    <!-- it's a good idea to initialize webchannel after DOM ready, if your code is going to manipulate the DOM --> 
    document.addEventListener("DOMContentLoaded", function() { 
     new QWebChannel(qt.webChannelTransport, function (channel) { 
      var jshelper = channel.objects.jshelper; 
      // do what you gotta do 
     }); 
    }); 
</script> 

Inoltre, assicurarsi di avere aggiunto QT += webenginewidgets webchannel al file .pro altrimenti questo non costruire!

Bonus: è possibile eseguire il debug di JavaScript dal comfort di Chrome Dev Tools ora!Basta aggiungere questo da qualche parte nel codice Qt (idealmente in avvio dell'applicazione):

#ifdef QT_DEBUG 
    qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "23654"); 
#endif 

Poi avviare l'applicazione, passare alla http://localhost:23654 in Chrome, e si otterrà un pieno-funzionale JS debugger, profiler, console, ecc :)


Follow-up (19/04/2016): se il debugger remoto non funziona, si noti che la chiamata qputenv deve verificarsi anche prima eventuali chiamate a QWebEngineSettings o qualsiasi altro Classe correlata al WebEngine, perché questo Attiva immediatamente il processo "zigote" di WebEngine (lo zigote è il genitore QtWebEngineProcess da cui sono state biforcate tutte le future QtWebEngineProcesses) e quindi non può influire su qputenv. Ho passato alcune ore a rintracciarlo.

+0

Questo è fantastico, il mio unico problema è che devo iniettare gli script perché non ho alcun controllo sulle pagine che vengono caricate. Inoltre, quando dici "il nuovo QT 5.5", intendi dal ramo dev? Sto usando QT Creator 5.5.0 e non sono sicuro di come sia aggiornato il codice sorgente QT da cui lavoro. Ho provato l'impostazione della variabile di ambiente per eseguire il debug di JS in una console ma non funziona (credo perché questa opzione di debug proviene da un commit recente). – mathieujofis

+0

Vedo. In Qt Creator, vai su Strumenti> Opzioni> Crea ed esegui> Versioni Qt e verifica quale versione hai. Quando dico Qt 5.5, intendo [la versione stabile che è stata rilasciata il 1 ° luglio di quest'anno] (http://blog.qt.io/blog/2015/07/01/qt-5-5-released/) . Qt 5.5 ha aggiunto il supporto integrato per Chromium IPC su QWebChannel (ad esempio, 'QWebEnginePage :: setWebChannel()' e 'qt.webChannelTransport' in JS). Inoltre, il tuo Qt Creator non può essere alla v5.5, [l'ultima versione è la v3.4.2] (http://blog.qt.io/blog/2015/07/01/qt-creator-3-4-2- rilasciato /) :) –

+0

Inoltre, 'QTWEBENGINE_REMOTE_DEBUGGING' è presente nella versione Qt 5.5: http://stackoverflow.com/a/29721197/504611 –

Problemi correlati