2017-04-20 70 views
2

我必须将我的代码移植到QT 5.8。不幸的是,现有的代码不再工作,因为QWebEngine的接口改变了。改变最简单的部分后,通过搜索和替换,我被困在使用新的QWebChannel类。最小QWebChanel示例不起作用

我只是没有得到它正常工作。在我的小工具中,我允许客户使用JQuery轻松填充内容的HTML模板。通过将我的C++应用程序的值传输到一个简单的Javascript代码,这非常有效。

但我无法使用新的Qt 5.8。 QWebChannel接口。我还尝试使用--remote-debugging-port=10命令行开关和Chrome开发人员工具对其进行调试。

qt.webChannelTransport是Chrome调试器已知的。但它不知道类QWebChannel?奇怪的是,$(document).ready(...)的代码永远不会执行。

如果我在Chrome Developers Tools控制台中输入qt.webChannelTransport.send("234234"),程序将崩溃。

因此,我决定做一个最简单的例子来说明我想实现的目标。熟悉正确用法的人应该很容易。我也无法使用我的Visual Studio调试Javascript代码,甚至不确定这是否可能以某种方式?

我很抱歉所有这些冗长的代码,但它似乎是最接近得到一个工作的例子。

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> 

这是我的Chrome调试我的程序后说:

Chrome Developer Tool

回答

0

使用Chrome开发者工具我能够获得我的程序的运行版本。这些错误大多是微妙的,很难调试。

我在这里发布我的代码以帮助其他人解决同样的问题。

潜在的错误,其中:

  • 格式不正确的HTML
  • Javascript文件未找到(处于错误的地方)
    • 我现在把它们放在一个资源文件。
    • 看一看Example.html!
  • Javascript错误
    • Chrome开发者工具是这里大量使用
  • 的Javascript extractKeys()功能被称为在错误的地方

的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

​​

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"></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>