Qt与JS数据交互

QT版本:5.6.2

核心类:QWebEngineView, QWebChannel 

1、C++和HTML通过websocket通信,通过官方的 qwebchannel.js 实现。

2、C++和HTML共用一个对象并以此进行通信,即通过QWebChannel的registerObject函数。
void QWebChannel::registerObject(const QString &id, QObject *object)

3、C++通知HTML:通过信号将数据传给JS(例如signalToWeb), 故可发送信息。

4、HTML通知C++:直接调用槽函数(必须是槽函数)
 
5、如果有多处使用了QWebEngineView, 则多个QWebEngineView可以共享同一个QWebChannel,因此可以讲QWebChannel定义为一个全局的单例对象,并通过其注册多个Cpp对象。
void QWebEnginePage::setWebChannel(QWebChannel *channel);
m_webEngineView->page()->setWebChannel(m_webChannel);

6、重要:
1)触发发送信号(例如signalToWeb)的按钮不要放在设计师界面,因为UI模式的点击事件上发信号在该组件会出现无法响应的bug(5.7.1)。
2)在给HTML传数据之前,要确保其已经load加载完成了,因为load和setUrl都是异步的,所以需要使用信号-槽连接(在槽里面完成数据的传送)。
void QWebEngineView::load(const QUrl &url)
void QWebEngineView::setUrl(const QUrl &url)
connect(m_webEngineView, SIGNAL(loadFinished(bool)), this, SLOT(slotSendDataToH5(bool)));

m_webEngineView->setUrl(QUrl("D:/testJsCallCpp/resources/index.html"));

C++代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 

#include "document.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    QJsonObject getUserInfoFromCpp();

private slots:
    void slotSendDataToH5(bool ok);

private:
    Ui::MainWindow *ui;

    QWebEngineView *m_webEngineView;
    QWebChannel *m_webChannel;
    Document m_content;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

const QString HttpUserAgent_H5 = QString("Toon-pc/1.0.0 windows,android,iphone,ipad");

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_webEngineView = new QWebEngineView();
    m_webEngineView->setContextMenuPolicy(Qt::NoContextMenu);
    m_webChannel = new QWebChannel();

    m_webChannel->registerObject(QStringLiteral("cppObject"), &m_content);
    m_webEngineView->page()->setWebChannel(m_webChannel);
    m_webEngineView->page()->profile()->setHttpUserAgent(HttpUserAgent_H5);

    connect(m_webEngineView, SIGNAL(loadFinished(bool)), this, SLOT(slotSendDataToH5(bool)));
    //m_webEngineView->setUrl(QUrl("https://www.baidu.com"));
    m_webEngineView->setUrl(QUrl("D:/testJsCallCpp/resources/index.html"));

    this->setCentralWidget(m_webEngineView);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QJsonObject MainWindow::getUserInfoFromCpp()
{
    QJsonObject json;
    json.insert("header", QStringLiteral("I am Qt!"));
    return json;
}

void MainWindow::slotSendDataToH5(bool ok)
{
    if (ok)
        m_content.sendJsonToWeb(getUserInfoFromCpp());
    else
        qDebug()<<"load failed! ok="<
#ifndef DOCUMENT_H
#define DOCUMENT_H

#include 
#include 
#include 

Q_DECLARE_METATYPE(QJsonObject)

class Document : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QJsonObject m_json READ getJson NOTIFY signalToWeb)

public:
    explicit Document(QObject *parent = nullptr) : QObject(parent)
    {
        qRegisterMetaType("QJsonObject");
    }


    QJsonObject getJson() const
    {
        return m_json;
    }

    // cpp端直接通过对象调用
    void sendJsonToWeb(const QJsonObject &json)
    {
        if (m_json != json)
        {
            m_json = json;
            emit signalToWeb(json);
        }
    }

signals:
    void receiveTextFromWeb(const QString &text);

    // js端通过注册的对象ID调用
public slots:
    // 必须为槽函数
    void sendTextToCpp(const QString &text)
    {
        qDebug()<<"******from web*******text="<

HTML代码:





  
  
  


  

运行效果:

Qt与JS数据交互_第1张图片

Qt与JS数据交互_第2张图片

你可能感兴趣的:(Qt,项目实战)