前面一节已经介绍了如何编译miniblink库以及如何在qt下使用,但是创立的是个独立窗体,应用中我们经常用到的是作为一个子窗体嵌入到其他窗体之中,类似QWebengnieView,本节将实现这个功能。

首先参考前一节将需要的库文件,头文件引入工程。

1.创建一个类QMiniblinkWebView继承自QWidget

2.初始化initialize接口

由于miniblink使用需要先初始化,这里设计在构造函数中处理这个问题,多个QMiniblinkWebView只需要初始化一次,所以这里定义两个静态变量

static bool _isInit;

static int _viewCount;

_isInit 用户判断是否初始化,_viewCount用户判断当前有多少个QMiniblinkWebView实例, 每次创建实力自动加一,当_viewCount为0时自动释放miniblink。为了方式 拷贝构造和复制私有化这两个函数

private:
    QMiniblinkWebView & operator == (const QMiniblinkWebView&){}
    QMiniblinkWebView(const QMiniblinkWebView&){}

初始化函数实现如下:

void QMiniblinkWebView::initialize()
{
    QString nodePath = QApplication::applicationDirPath() + "/node.dll";
    if(!QFile::exists(nodePath))
    {
        qDebug()<<QStringLiteral("请将node.dll拷贝到运行目录");
        return;
    }
    std::vector<wchar_t> tempPath;
    tempPath.resize(MAX_PATH);
    nodePath.toWCharArray(&tempPath[0]);
    wkeSetWkeDllPath(&tempPath[0]);

wkeInitialize();
    _isInit = true;
    ++QMiniblinkWebView::_viewCount;
}

3. 释放接口

当前实力为0时 释放miniblink

void QMiniblinkWebView::finalize()
{
    if(--QMiniblinkWebView::_viewCount == 0)
    {
        wkeFinalize();
        _isInit = false;
    }
}

4.创建miniblinkview

调用wkeCreateWebWindow(WKE_WINDOW_TYPE_TRANSPARENT, (HWND)this->winId(), 0, 0, width(), height()); 进行创建,此处创建的是一个window

5.将步骤4创建的view子类化为QtWidget子窗体

通过wkeGetWindowHandle(viewer)可以拿到wkeCreateWebWindow创建的viewer的窗口句柄,然后调用windows函数SetParent建立父子关系

SetParent(wkeGetWindowHandle(viewer), (HWND)this->winId());

6.大小改变

4,5创建的窗体是固定大小,当我们改变QWidget大小时,wkeCreateWebWindow创建的viewer大小并不会随之改变,我们需要截获QWidget大小改变通知。你可能会想到继承QWidget::resizeEvent,经我实践,wkeCreateWebWindow创建的窗口影响了这个事件

获取的大小不正确。所以这里依旧使用windows窗口回调来实现。

调用SetWindowSubclass为qt窗体设置一个回调函数 SetWindowSubclass((HWND)this->winId(), subClassProc, 0, (DWORD_PTR)this);

回调函数的实现如下,这是一个静态成员函数,也可以写成一个全局函数。

LRESULT CALLBACK QMiniblinkWebView::subClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    QMiniblinkWebView *obj = (QMiniblinkWebView *)dwRefData;
    if(obj == nullptr)
        return DefSubclassProc(hWnd, uMsg, wParam, lParam);
    switch (uMsg) {
    case WM_SIZE:
         obj->autojustWebViewSize();
        break;
    default:
        break;
    }
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

这里只做了一件事,就是调用接口autojustWebViewSize实现viewer跟谁qt父窗口大小改变。

void QMiniblinkWebView::autojustWebViewSize()
{
    //此处如果用qt得方法获取大小在最大化最小化有问题,故改为通过windows函数获取,可能是qt版本问题
    //wkeMoveWindow(_viewer, 0, 0, width(), height());
    RECT rect;
    GetWindowRect((HWND)this->winId(), &rect);
    wkeMoveWindow(_viewer, 0, 0, rect.right - rect.left, rect.bottom - rect.top);

}

此处如果用qt得方法获取大小在最大化最小化有问题,故改为通过windows函数获取,可能是qt版本问题。

自此我们就基本完成了miniblink集成到qt了,可以将QMiniblinkWebView作为独立窗口使用,也可以作为任意一个qt窗口的子窗体使用。

7.事件通知

miniblink的通知是回调机制,wke.h 包含了所有的函数定义以及回调的函数指针定义,我们需要获取到什么通知就定义个相应函数指针类型的回调函数就可以活得通知,我这里实现了常用的几个通知,然后转化为qt信号的方式发出去。

wkeWebView viewer = wkeCreateWebWindow(WKE_WINDOW_TYPE_TRANSPARENT, (HWND)this->winId(), 0, 0, width(), height());
    if (!viewer)
        return nullptr;
    wkeSetWindowTitleW(viewer, title.toStdWString().c_str());
    wkeOnDocumentReady(viewer, handleDocumentReady, nullptr);
    wkeOnLoadUrlBegin(viewer, onLoadUrlBegin, (void *)this);
    wkeOnLoadUrlEnd(viewer, onLoadUrlEnd, (void *)this);
    wkeOnLoadUrlFail(viewer, onLoadUrlFailed, (void *)this);
    wkeOnLoadingFinish(viewer, onLoadingFinish, (void *)this);
    //wkeMoveToCenter(viewer);
    SetWindowSubclass((HWND)this->winId(), subClassProc, 0, (DWORD_PTR)this);
    SetParent(wkeGetWindowHandle(viewer), (HWND)this->winId());
    wkeMoveWindow(viewer, 0, 0, width(), height());

//文档加载完成

static void handleDocumentReady(wkeWebView webWindow, void* param);

//开始加载
    static bool onLoadUrlBegin(wkeWebView webView, void* param, const char* url, void *job);

//加载完,并不一定是成功的
    static void onLoadUrlEnd(wkeWebView webView, void* param, const char *url, void *job, void* buf, int len);

//加载失败
    static void onLoadUrlFailed(wkeWebView webView, void* param, const utf8* url, wkeNetJob job);

//加载完成,failedReason包含了失败的原因
    static void onLoadingFinish(wkeWebView webView, void* param, const wkeString url, wkeLoadingResult result, const wkeString failedReason);

由于都是回调函数,需要定义成静态成员函数或者全局函数,函数的参数可以直接看wke.h。需要其他回调的可以参考wke.h自己添加比如下载的进度等等。

bool QMiniblinkWebView::onLoadUrlBegin(wkeWebView webView, void* param, const char* url, void *job)
{
    QMiniblinkWebView *obj = (QMiniblinkWebView *)param;
    if(obj != nullptr)
    {
        emit obj->loadStarted();
    }
    return true;
}

void QMiniblinkWebView::onLoadUrlEnd(wkeWebView webView, void* param, const char *url, void *job, void* buf, int len)
{
    QMiniblinkWebView *obj = (QMiniblinkWebView *)param;
    if(obj != nullptr)
    {
        emit obj->loadFinished(true);
    }
}

void QMiniblinkWebView::onLoadUrlFailed(wkeWebView webView, void* param, const utf8* url, wkeNetJob job)
{
    QMiniblinkWebView *obj = (QMiniblinkWebView *)param;
    if(obj != nullptr)
    {
        emit obj->loadUrlFail();
    }
}

void  QMiniblinkWebView::onLoadingFinish(wkeWebView webView, void* param, const wkeString url, wkeLoadingResult result, const wkeString failedReason)
{
    QMiniblinkWebView *obj = (QMiniblinkWebView *)param;
    if(obj != nullptr && result == WKE_LOADING_SUCCEEDED)
    {
        emit obj->loadFinished(true);
    }
}

自此,一个简单的qt版miniblink封装已经完成

8.使用

1.独立窗口

QMiniblinkWebView w2;
    w2.show();
    //w2.loadFile("./debug/2.html");
    w2.load("http://baidu.com");

2.子窗体

QMiniblinkWebView *w2 = new QMiniblinkWebView("http://baidu.com", this);
    setCentralWidget(w2);

代码都很简单,主要步骤为5.将步骤4创建的view子类化为QtWidget子窗体,如果需要完整源码,可以留言。

下一节将介绍如何实现js与C++得通信

Qt 集成miniblink浏览器库之2封装相关推荐

  1. Qt 集成miniblink浏览器库之4 解决兼容性问题

    之前介绍了如何miniblink集成到qt,采用wkeCreateWebWindow来创建一个浏览器窗口,wkeCreateWebWindow有三种方式 typedef enum _wkeWindow ...

  2. Qt 集成miniblink浏览器库之1编译使用

    1.miniblink简介 miniblink是一款精简小巧的浏览器控件,由龙泉寺扫地僧基于chromium精简而成,是市面上最小巧的chromium内核控件没有之一. 它仅10余M大小,只需一个dl ...

  3. Qt 集成miniblink浏览器库之5 支持独立窗口和子窗口

    前面使用GDI绘制解决了集成到Qt的系统冲突和QWebEngineView的冲突,但仅支持作为qt的子窗体,现在将其修改为支持独立窗口的创建. 首先判断create接口传入的父窗口句柄是否是空,为空表 ...

  4. 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )

    文章目录 安卓直播推流专栏博客总结 一. x264 简介 二. x264 交叉编译 三. Android Studio 导入函数库 四. 交叉编译版本 五. GitHub 项目地址 安卓直播推流专栏博 ...

  5. Qt调用CUDA动态库及配置

    本文配置环境:Win7(x64)+VS2012+CUDA+Qt5.5.0 1.首先保证CUDA集成到VS下(如下图顺利安装Nsight for VS2012).CUDA安装比较简单,选自定义安装,然后 ...

  6. Qt框架与STL库之间的巅峰对决:差异、优缺点及适用场景

    Qt框架与STL库之间的巅峰对决:差异.优缺点及适用场景 引言 对比的重要性 Qt框架与STL库简介 博客内容概览 Qt框架基础 Qt框架的特点与组成 Qt的信号槽机制 Qt容器类简介 数据结构的对比 ...

  7. 旺谷图控与QT集成开发

    1.与QT集成开发 1.1旺谷图控QT开发包 QT开发包中包含:头文件.静态库.动态库.元件库.vgs工程或元件组成.其中元件库和vgs工程由vgs开发工具发布,拷贝到Qt工程的debug和relea ...

  8. Qt 配置使用IPP库

    Inter IPP库的简介与配置 1.Inter IPP库简介 IPP"Intel Integrated Performance Primitives" ( Intel IPP ) ...

  9. QT——移植官方MQTT库

    1.软件版本 QT5.12.10 Win11 mingw 2.概述 Qt开发MQTT程序有两种方式,一个是Qt官方提供的基于MQTT的封装,一个是第三方(EMQ)开发的用于Qt调用MQTT的接口,二者 ...

最新文章

  1. urlrewrite实现之HTTP 运行库支持
  2. juniper防火墙做ipsec ***必须开放的端口
  3. [Github]watch和star的区别
  4. IDM ultraEdit27中文版
  5. html画布显示PPT,【Web前端问题】有没有办法让HTML5 canvas显示/预览word/excel/powerpoint 文档?...
  6. 实验1 Windows汇编语言开发环境
  7. Java高并发编程详解系列-Java线程入门
  8. 转:【微信小程序】实现锚点定位楼层跳跃的实例
  9. LG WP7机型工程模式下越狱
  10. 新华三模拟器IRF配置
  11. iOS NSString URLencode
  12. SlidingMenu第三篇 --- SlidingMenu使用介绍
  13. 如何破解CuteFTP 4.0,CuteFTP,逆向工程技术
  14. 水晶报表html,水晶报表教程:手把手教你制作基本报表
  15. matlab 复制 模块,想把m文件在simulink 中的调用,我用的是matlab function 模块。
  16. 微信小商店购物组件接入现有的小程序,在开发者工具中使用
  17. Linux系统安装与使用基础之第二篇熟悉Linux操作系统
  18. java ipmi 获取服务器硬件信息(温度,风扇转速,内存数,硬盘数等等)
  19. ArcGIS JS之 4.23之IIS本地部署与问题解决
  20. 嵌入式(stm32)学习之路---MIDI音乐播放器

热门文章

  1. HTML学生个人网站作业设计:动漫网站设计——柯南(5页) HTML+CSS+JavaScript 简单DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  2. 思科实验-3.3.1.5-Packet Tracer - 配置 PVST+
  3. 腾讯云tca认证是什么?腾讯云tca认证题库有哪些内容?
  4. 程序人生:化解互联网 “寒冬” 危机,我教你摆脱困境
  5. Python3中的StringIO
  6. 如何启用或禁用“Fn”键与“F1——F12”键的联用?
  7. Vue非父子组件传值
  8. python 协程是啥_Python协程
  9. Tigase8.1.2安装配置
  10. 获取p的value值