2017-04-20 3 views
2

Je dois porter mon code à QT 5.8. Malheureusement, le code existant ne fonctionne plus, car l'interface de QWebEngine a changé. Après avoir modifié les portions les plus faciles, en cherchant et en remplaçant, j'ai été piégé en utilisant la nouvelle classe QWebChannel.Exemple minimal QWebChanel ne fonctionne pas

Je n'arrive simplement pas à le faire fonctionner correctement. Dans mes widgets, j'ai permis au client de remplir facilement des modèles HTML avec du contenu en utilisant JQuery. Cela a très bien fonctionné en transportant les valeurs de mon application C++ vers un simple code Javascript.

Mais je n'ai pas pu utiliser le nouveau Qt 5.8. Interface QWebChannel. J'ai également essayé de le déboguer en utilisant le commutateur de ligne de commande --remote-debugging-port=10 et les outils de développement Chrome.

qt.webChannelTransport est connu du débogueur Chrome. Mais il ne connaissait pas la classe QWebChannel? Bizarrement, le code pour $(document).ready(...) n'est jamais exécuté.

Si je tape qt.webChannelTransport.send("234234") dans la console des outils du développeur Chrome, le programme se bloque.

J'ai donc décidé de faire un exemple minimal pour illustrer ce que je voulais réaliser. Il devrait être facile pour quelqu'un de connaître l'utilisation correcte. J'ai également été incapable de déboguer le code Javascript en utilisant mon Visual Studio, même si je ne sais pas si c'est possible d'une manière ou d'une autre?

Je suis désolé pour tout ce long code, mais il semble être le plus proche d'obtenir un exemple de travail.

Main.cpp

#include <QWebChannel> 
#include <QWebEngineView> 
#include <QApplication> 
#include <QFile> 
#include "JsWebPage.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    auto view = new QWebEngineView; 

    view->setPage(new JsWebPage); 

    QFile file(":/Example.html"); 
    if (!file.open(QIODevice::ReadOnly)) return false; 
    QString content = QString::fromUtf8(file.readAll()); 
    view->setHtml(content); 
    file.close(); 
    //view->page()->setHtml(content); 
    view->show(); 
    return app.exec(); 
} 

JsWebPage.h

#pragma once 

#include <QWebEnginePage> 

class JsWebPage : public QWebEnginePage { 
    Q_OBJECT 

public: 
    JsWebPage(); 

    void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) override; 

private: 
    QWebChannel* mWebChannel = nullptr; 
}; 

JsWebPage.cpp

#include "JsWebPage.h" 
#include <QWebChannel> 
#include <QWebEngineSettings> 
#include <QWebEnginePage> 
#include <QDebug> 

void JsWebPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) 
{ 
    qDebug() << QString("Javascript Console: Line: %1, Source: %2, %3").arg(lineNumber).arg(sourceID).arg(message); 
} 

JsWebPage::JsWebPage() 
{ 
    settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); 
    settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); 

    mWebChannel=new QWebChannel; 
    mWebChannel->registerObject(QString("qtObject"), this); 
    setWebChannel(mWebChannel); 
} 

example.js

new QWebChannel(
    qt.webChannelTransport, 
    function(channel) { 
     var qtObject = channel.objects.qtObject; 
     console.log("Hello world"); 
     // Code for replacing using jQuery 
     // <div id="myTag1"></div> 
     // by 
     // <div id="myTag1">Content</div> 
    } 
); 

$(document).ready(
    console.log("READY"); // Program never reached this point. Why? 
); 

example.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 
    <script src="jquery.js" type="text/javascript"></script> 
    <script src="qwebchannel.js" type="text/javascript"></script> 
    <script src="example.js" type="text/javascript"></script> 
    <title>Template</title> 
</head> 
<body id="Body"> 
    Example HTML 
    <div id="myTag1"></div> 
    <div id="myTag2"></div> 
</body> 
</html> 

Voici ce que je dis après le débogage mon programme avec Chrome:

Chrome Developer Tool

Répondre

0

Utilisation des outils de développement Google Chrome J'ai pu obtenir une version en cours de mon programme. Les erreurs étaient la plupart du temps subtiles et difficiles à déboguer.

Je poste mon code ici pour aider d'autres personnes aux prises avec le même genre de problèmes.

erreurs potentielles où:

  • HTML malformée
  • fichiers Javascript ne sont pas trouvés (être au mauvais endroit)
    • Je les en train de mettre tous dans un fichier de ressources.
    • Jetez un coup d'œil dans Example.html!
  • erreurs Javascript
    • Outils de développement Chrome sont d'une grande utilité ici
  • Javascript extractKeys() fonction a été appelée au mauvais endroit

main.cpp

#include <QWebChannel> 
#include <QWebEngineView> 
#include <QApplication> 
#include <QFile> 
#include "JsWebPage.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    auto view = new QWebEngineView; 

    view->setPage(new JsWebPage); 

    QFile file(":/Example.html"); 
    if (!file.open(QIODevice::ReadOnly)) return false; 
    QString content = QString::fromUtf8(file.readAll()); 
    view->setHtml(content); 
    file.close(); 
    view->show(); 
    return app.exec(); 
} 

JsWebPage.h

#pragma once 

#include <QWebEnginePage> 

class JsWebPage : public QWebEnginePage { 
    Q_OBJECT 

public: 
    JsWebPage(); 

    void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) override; 

signals: 
    void extractKeys(); 

public slots: 
    void onKeysExtracted(QStringList keys); 

private: 

    QWebChannel* mWebChannel = nullptr; 
}; 

JsWebPage.cpp

#include "JsWebPage.h" 
#include <QWebChannel> 
#include <QWebEngineSettings> 
#include <QWebEnginePage> 
#include <QDebug> 

void JsWebPage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) 
{ 
    qDebug() << QString("Javascript Console: Line: %1, Source: %2, %3").arg(lineNumber).arg(sourceID).arg(message); 
} 

void JsWebPage::onKeysExtracted(QStringList keys) 
{ 
    qDebug() << keys; 
} 

JsWebPage::JsWebPage() 
{ 
    settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); 
    settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); 

    mWebChannel=new QWebChannel; 
    mWebChannel->registerObject(QString("qtObject"), this); 
    setWebChannel(mWebChannel); 
} 

exemple.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta> 
    <script src="qrc:///jquery.js" type="text/javascript"></script> 
    <script src="qrc:///qwebchannel.js" type="text/javascript"></script> 
    <script src="qrc:///example.js" type="text/javascript"></script> 
    <title>Template</title> 
</head> 
<body id="Body"> 
    Example HTML 
    <div id="myTag1"></div> 
    <div id="myTag2"></div> 
</body> 
</html> 

example.js

var webChannel=new QWebChannel(
    qt.webChannelTransport, 
    function(channel) { 
     extractKeys(); 
    } 
); 

function extractKeys() { 
    try { 
     var valueTable = []; 
     $("[id]").each(
      function() { 
       valueTable.push($(this).attr("id")); 
      } 
     ); 
     webChannel.objects.qtObject.onKeysExtracted(valueTable); 
    } 
    catch (e) { 
     console.log(e); 
    } 
} 

resource.qrc

<!DOCTYPE RCC><RCC version="1.0"> 
<qresource> 
<file>Example.html</file> 
<file>example.js</file> 
<file>qwebchannel.js</file> 
<file>jquery.js</file> 
</qresource> 
</RCC>