QWebView到QWebEngineView

  1. vs2013中的Qt5插件从Qt Project Settings中没有能引入QWebEngineView和QWebChannel的模块,我们可以在vs2013中手动加入。
    附加包含目录: (QTDIR)\include\QtWebEngineWidgets (QTDIR)\include\QtWebChannel
    附加依赖项:Qt5WebEngineWidgetsd.lib, Qt5WebChanneld.lib
  2. page()->mainFrame()->evaluateJavaScript(str);
    => page()->runJavaScript(str);
  3. QWebSettings
    => QWebEngineSettings
  4. QWebHistory
    => QWebEngineHistory
  5. page()->mainFrame()->load
    => page()->load
  6. Incorrect warning MSB8027 reported for files excluded from build

    vs2013更新到update5,或者
    文本编辑器打开project插入: IgnoreWarnCompileDuplicatedFilename


    true

  7. evaluateJavaScript
    => runJavaScript

  8. evaluateJavaScript返回值
    => 使用异步回调接受[](const QVariant &val) { }
  9. 设置QWebEngineView背景色
    => page()->setBackgroundColor(QColor(“#0f0f10”));

  10. Qt WebEngine ICU data not found The application MAY NOT work. Installed Qt WebEngine locales directory not found at location
    => 增加resources和translations目录,具体放的位置可以看日志哪里可以找到它,可以通过qt.conf文件来配置所在路径

  11. QWebEngineView调试

    方法1:html中加入https://getfirebug.com/firebug-lite.js, 在页面上按F12打开调试面板
    缺点:这个js文件比较大,载入的时候影响效率;功能有限;
    方法2:在程序开始的时候qputenv(“QTWEBENGINE_REMOTE_DEBUGGING”, 9000),之后在chrome中打开网址:localhost:9000
    就可以看到QWebEngineView加载的html了,点击相应的html可以打开chrome的开发者工具;
    这个方法比上面的好得多。

  12. linkClicked(QUrl)
    重载QWebEnginePage实现acceptNavigationRequest接口

bool WebPage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
{
    if (isMainFrame) {
        if (NavigationTypeLinkClicked == type) {
            emit sigLoadUrl(url);
            return false;
        }
    }
    return true;
}
  1. 同步返回runJavaScript结果,谨慎使用
QPair<bool, QVariant> syncRunJavaScript(QWebEnginePage *page, const QString &javascript, int msec) 
{
     QPair<bool, QVariant> result = qMakePair(false, 0);
     QSharedPointer loop = QSharedPointer(new QEventLoop());
     QTimer::singleShot(msec, loop.data(), &QEventLoop::quit);
     page->runJavaScript(javascript, [loop, &result](const QVariant &val) {
         if (loop->isRunning()) {
             result.first = true;
             result.second = val;
             loop->quit();
         }
     });
     loop->exec();
     return result;
 }

在QWebEngineView重载函数contextMenuEvent中不能调用!
runJavaScript回调中不能进行长时间的操作,否则会阻塞JavaScript代码执行,如:

page()->runJavaScript("script", [](const QVariant &val) {
    // ...
    menu.exec(QCursor::pos());
}

解决办法,定义信号和槽函数,使用QueuedConnection的方式connect,在slotJavaScriptResult中处理耗时操作。

connect(this, &webview::sigJavaScriptResult, this, &webview::slotJavaScriptResult, Qt::QueuedConnection);
void sigJavaScriptResult(const QString &command, const QVariantMap &result);
void slotJavaScriptResult(const QString &command, const QVariantMap &result);
  1. runJavaScript时机
connect(this->page(), SIGNAL(loadFinished(bool)), this, SLOT(finish(bool)));
  1. js调用C++时机
window.cppobj = null;
new QWebChannel(qt.webChannelTransport, function(channel) {
  window.cppobj = channel.objects.cppobj;
  cppobj.init(); // 通知C++初始化完成
});
  1. web页面,右键鼠标点击的元素

    function contextMenu(e) {
    var targ;
    if (!e) {
    var e = window.event;
    }
    if (e.target) {
    targ = e.target;
    } else if (e.srcElement) {
    targ = e.srcElement;
    }
    }
    
  2. web页面,获取选中的html
 function getHTMLOfSelection () {
  var range;
  if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();
    return range.htmlText;
  }
  else if (window.getSelection) {
    var selection = window.getSelection();
    if (selection.rangeCount > 0) {
      range = selection.getRangeAt(0);
      var clonedSelection = range.cloneContents();
      var div = document.createElement('div');
      div.appendChild(clonedSelection);
      return div.innerHTML;
    }
    else {
      return '';
    }
  }
  else {
    return '';
  }
}
  1. QWebEngineView接收drop事件
之前setAcceptDrops(true);就可以了,现在还需要:
void webview::dragEnterEvent(QDragEnterEvent *event)
{
    event->accept();
    QWebEngineView::dragEnterEvent(event);
}
才能触发void webview::dropEvent(QDropEvent * event)
  1. web打印日志
    重载QWebEnginePage中的javaScriptConsoleMessage函数很有用,可以接收到js打印的日志(如:console.log);
  2. 一个QWebEnginePage对应一个QtWebEngineProcess.exe进程,所以当web页窗口不显示的时候最好是销毁掉,不要隐藏;
  3. 某些机器上QWebEngineView内容显示不出来可能跟设置背景色有关;
  4. js与c++之间互调返回值处理
    QWebEngineView中c++调用js代码是通过异步回调的方式获取的;
    js调用c++的函数并不能获取c++函数的返回值,可以通过c++发送一个信号给js来返回。

你可能感兴趣的:(qt)