最简单的基于QWebEngineWidgets实现的c++ js混合开发

原文地址:点击打开链接

背景:

qt4到qt5.4一直采用qwebkit实现c++ js混合编程,到qt5.5之后引入了qwebenginewidgets和qwebchannel来代替qwebkit,从qt5.6之后开始,qwebkit就不再被支持了。

Qt新版本使用QWebEngineView来展示html页面对QWebView不再进行维护了,QWebEngineView使用chromium内核将带来更好的用户体验。

对QWebView感兴趣的可以参考:http://blog.csdn.net/tujiaw/article/details/50372892

从QWebView到QWebEngineView,参考:http://blog.csdn.net/tujiaw/article/details/52075495

  • C++调用js很简单

    m_view->page()->runJavaScript("showAlert()");
    • 1
  • js调用C++函数

     QWebChannel *channel = new QWebChannel(this);
    channel->registerObject("bridge", (QObject*)bridge::instance());
    m_view->page()->setWebChannel(channel);
    • 1
    • 2
    • 3

注意这个bridget类最好是从QObject继承,不要直接使用Dialog,否则你会看到一些莫名其妙的错误日志,而且使用一个中间类也可以解耦C++与js/html之间的逻辑

源码如下,地址: 
main.cpp

#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

namespace Ui {
class Dialog;
}

class QWebEngineView;
class Dialog : public QDialog
{
    Q_OBJECT

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

private:
    Ui::Dialog *ui;
    QWebEngineView *m_view;
};

#endif // DIALOG_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QWebEngineView>
#include <QWebChannel>
#include <QDir>
#include <QDebug>
#include "bridge.h"

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

    m_view = new QWebEngineView(this);
    QWebChannel *channel = new QWebChannel(this);
    channel->registerObject("bridge", (QObject*)bridge::instance());
    m_view->page()->setWebChannel(channel);
    m_view->page()->load(QUrl(QString("file:///%1/%2").arg(QApplication::applicationDirPath()).arg("index.html")));

    ui->viewLayout->addWidget(m_view);
    connect(ui->pbAlert, &QPushButton::clicked, [this]() {
        m_view->page()->runJavaScript("showAlert()");
    });
}

Dialog::~Dialog()
{
    delete ui;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

bridge.h

#ifndef BRIDGE_H
#define BRIDGE_H

#include <QObject>

class bridge : QObject
{
Q_OBJECT
public:
    static bridge* instance();

public slots:
    void showMsgBox();

private:
    bridge();
};

#endif // BRIDGE_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

bridge.cpp

#include "bridge.h"
#include <QMessageBox>

bridge* bridge::instance()
{
    static bridge s_obj;
    return &s_obj;
}

bridge::bridge()
{
}

void bridge::showMsgBox()
{
    QMessageBox::aboutQt(0, tr("Qt"));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
    <script src="./qwebchannel.js"></script>
  </head>
  <body style="background:#282c34;">
    <h3 style="color:#ffffff;">this is web page</h3>
    <input type="button" value="C++ function callback" onclick="onShowMsgBox()">
    <script>
      new QWebChannel(qt.webChannelTransport, function(channel) {
        window.bridge = channel.objects.bridge;
      })
      function onShowMsgBox() {
        if (bridge) {
          bridge.showMsgBox()
        }
      }

      function showAlert() {
        alert('this is web alert');
      }
    </script>
  </body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

qwebchannel.js是Qt提供的可以在这里下载:https://code.csdn.net/tujiaw/webengineview/tree/master/qwebchannel.js

运行的时候index.html和qwebchannel.js这两个文件放在与exe同级目录下


猜你喜欢

转载自blog.csdn.net/jigetage/article/details/80968167