最小的QWebChanel示例不起作用

时间:2017-04-20 08:04:52

标签: javascript c++ qt qwebview qwebkit

我必须将我的代码移植到QT 5.8。遗憾的是,现有代码不再起作用,因为QWebEngine的界面发生了变化。在更改最简单的部分后,通过搜索和替换,我被困在使用新的QWebChannel类。

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

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

Chrome调试器已知

qt.webChannelTransport。但它不知道班级QWebChannel?奇怪的是,$(document).ready(...)的代码永远不会被执行。

如果我在Chrome开发者工具控制台中输入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

1 个答案:

答案 0 :(得分:1)

使用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

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

<强> 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>