Qt5.6中使用的webview是基于chromium45来实现的,叫做QtWebEngine,之前使用QtWebkit已经被废弃,因此webview的兼容性也非常不错;不过由于引入了多进程架构,导致bridge机制比较复杂,需要引入WebChannel的概念,底层是使用websocket来实现的。

使用webview

QMainWindow * widget = new QMainWindow(this);
QWebEngineView * webview = new QWebEngineView(this);
widget->setCentralWidget(webview);
widget->show();

// load url
std::wstring url = L"http://www.suninf.net/";
webview->load(QString::fromStdWString(destUrl.GetString()));

// set userAgent
webview->page()->profile()->setHttpUserAgent(webview->page()->profile()->httpUserAgent() + QStringLiteral(" suninf/1.0.0"));

bridge机制

创建sdk对象

class SDKObject : public QObject
{
  Q_OBJECT

public:
  SDKObject(QObject* parent);

public slots:
  // request
  void reqGetCurrentStatus(QString reqid);

signals:
  // response
  void onRspGetCurrentStatus(QString reqid, int status);

signals:
  // notify
  void onNotifyStart();
};

设置WebChannel

QWebChannel *channel = new QWebChannel(this);
channel->registerObject(QStringLiteral("tblive"), new SDKObject(this));

webview->page()->setWebChannel(channel);

前端页面对接

  1. 需要引入 qwebchannel.js
  2. 需要初始化QWebChannel,来获取注入的对象tblive
    document.addEventListener("DOMContentLoaded", function () {
        new QWebChannel(qt.webChannelTransport, function (channel) {
            window.tblive = channel.objects.tblive;
            initTblive();
        });
    });

参考:http://doc.qt.io/qt-5/qtwebchannel-javascript.html

远程调试

  1. 需要以命令行参数启动,如:--remote-debugging-port=9000
  2. 然后在浏览器中输入 http://localhost:9000 即可调试

注意:QtWebEngine5.6 在chrome升级到50后无法远程调试,需要降低到49版本

多进程架构

使用了QtWebEngine的app,自带了chrome的多进程架构,webview会跑在render进程,子进程名:QtWebEngineProcess.exe

因此,QtWebEngineProcess.exe文件也需要和应用一起发布