QWebView中JS和C++通信,利用QWebView生成图片

1.主要目标

  • 用最简单的代码实例相互通信

    • JS调用C++代码

    • C++调用JS代码

  • 利用QWebView渲染出png图片

2.介绍项目的情况

在项目中只要用到了浏览器组件,不关你是libcef,QWebEngine,QWebView,都少不了和前端通信的需求。

在QWebView中做到这些都是很简单的事情,通常也是几行代码的时候。但是也有点小坑要绕着走。

1.新建一个项目

使用QtCreator新建一个Widget项目的过程,我就省略了啊。里面自动帮我们创建一个widget.ui文件

我们直接在从designer的设计器里面,放一个QWebView控件和一个按钮(测试调用JS代码)

效果图如下:

 这是加载了百度之后的样式

 

2.代码实例

1.准备html文件

为了演示效果,我自己手写了一个简单的html文件。

<!DOCTYPE html>
<html>
 <head>
    <meta charset="utf-8">
    <title>FLOT DEMO</title>
	<script LANGUAGE="JavaScript">
		function jsFun(parameter) 
		{
			alert(parameter) 
			return "jsFun result"
		}
		
		function clickButton()
		{
                        Widget.doSomething('abc')
		}
	</script>
    </head>
    <body>
        <button type="button" onclick="clickButton()">Click Me!</button>
        <p>test html</p>
    </body>
	
</html>

我把这个文件放到了qrc资源里面去加载。

效果图如下:

2.调用js代码

void Widget::CallJsFunction()
{
    ui->webView->page()->mainFrame()->evaluateJavaScript("jsFun(\"json format data\")");
}

一行代码就调用了js代码

这里我就简单的解释下evaluateJavaScript(const QString & scriptSource)函数。

这个函数里面传递的参数从字面的意思上看就是你要执行的js代码。这是其一,我在测试的过程中发现其实它也可以传递js的函数名和参数。我在测试的时候就是这样用的。

点击Test call js弹出的是JS的提示。

 

3.调用C++代码

在调用C++的代码需要麻烦点,但是也没有多麻烦。跟我一起试下。

1.注册我们自己的对象

我们需要自己注册一个对象进去。不要慌,也没有几行代码。

// 1.首先链接一个信号
connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(OnJavaScriptWindowObjectCleared()));

// 2.信号处理函数
void Widget::OnJavaScriptWindowObjectCleared()
{
    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("Widget", new MyObject());
}

// 3.MyObject对象声明
class MyObject : public QObject {
    Q_OBJECT

public slots:
    void doSomething(const QString &data)
    {
        QMessageBox::information(nullptr, tr("From web call"), data, QMessageBox::Ok);
    }
};

2.html里面调用

function clickButton()
{
	Widget.doSomething('abc')
}

这个是Button的点击响应事件,里面用的Widget就是我们自己注册的。doSomething()就是调用了MyObject的成员函数。

效果图如下:

 

我们稍微总结下:

  1. 根据信号触发注册自定义的对象。

  2. JS段根据自定义的对象调用成员函数

嘿嘿,看起来还是很简单的。就是给我的感觉这种方式挺神奇的。有机会深挖下原理。

3.生成png图片

// 绑定页面加载完成的信号
connect(ui->webView, SIGNAL(loadFinished(bool)), this, SLOT(OnLoadFinished(bool)));

void Widget::OnLoadFinished(bool result)
{
    QString strUrl = ui->webView->url().toDisplayString();

    // render image
    if (result) {
        renderImage();
    }
    else{
        qDebug() << "load error";
    }
}

// 渲染图片的方法
bool Widget::renderImage()
{
    // 获取当前页面的大小
    QSize contentSize = ui->webView->page()->mainFrame()->contentsSize();
    // 声明一张图片大小和页面一样大
    QImage image = QImage(contentSize, QImage::Format_RGB32);
    // 设置page的可视窗口大小和页面的一样
    ui->webView->page()->setViewportSize(contentSize);
    QPainter painter(&image);
    // 绘制到painter上
    ui->webView->page()->mainFrame()->render(&painter);
    painter.end();
    // 保存
    image.save("D:\\test_web_render.png");
    return true;
}

上面的代码我做了详细的注释,就不再介绍了。

我尝试了百度效果图如下:

 

3.介绍QWebView的知识

刚才我相信大家基本骑了下自行车,快速的实践一遍。

这里我简单的介绍下QWebView的知识。我其实懂得不多,也是从官方的文档中学习的。

1.关系图

这张图从文档中截出来的,我觉得很简单的,一下子就介绍了几个class的关系。

2.注册对象

根据官方的文档介绍,我们在注册js对象的时候,要先连接javaScriptWindowObjectCleared()信号,再去注册对象。

因为在这里对象已经被全部清除,确保在加载新的地址时候,你的对象会被注册进去。否则加载的时机不对,你的对象就算加载进去,在加载新的URL可能会被清空。

## 4.总结

最后,总结下我遇到的问题。

* 在使用QWebView的时候一定要注意版本,为什么?因为QWebView这个组件使用的内核版本是非常低的,有可能新的特性它并不支持。
* 在加载https的时候,页面无法加载,通过查看错误信息发现,需要把两个dll`libeay32.dll ssleay32.dll`放到你的exe运行目录下。
* 使用file协议加载页面的时候需要使用绝对路径。我是查了RFC文档说明,file协议不支持相对路径。
* 渲染图片的时候,QWebView有时候获取的页面大小不对。我采取的做法是让前端调用我的接口返回正确的页面大小。

关于更多的QWebView,大家在遇到的时候再去查文档也不迟。

https://gitee.com/liushixiong/study-qt

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值