Qt/QML开发支持下载的简单浏览器
来源:互联网 发布:centos 7服务器dvd安装 编辑:程序博客网 时间:2024/06/06 03:05
之前有篇文章介绍过开发简易浏览器(文章标题:QML开发简单浏览器(加载H5)),当时主要介绍了如何使用QML的WebEngineView开发一个可以进行简单浏览网页的应用(仅仅是进行网页的浏览哦^_^),所以没有涉及到网页中下载的情况,这篇文章主要介绍如何利用QML开发出可以进行下载的浏览器,实现将网上的图片和文件下载到本地。
话不多说,先奉上【干货代码】,再奉上【效果图】,最后有【深度解析】。
【干货代码】如下:
所以,当给WebEngineView设置了profile属性后,当WebEngineProfile发送downloadRequested信号时,我们就可以转入到我们自己的函数中,涉及到信号与槽,就必须对信号槽进行连接,因此,在打开新页面初次,我们添加了如下代码:
if (windowParent.isInit) {
profile.downloadRequested.connect(newWindow.onDownloadRequested)
profile.downloadFinished.connect(newWindow.onDownloadFinished)
windowParent.isInit = false;
}
将发送下载请求信号和下载完成信号与对应的槽函数进行连接。至于为什么要用windowParent.isInit进行控制,大家都知道,Qt中如果信号和槽连接多次,那么当信号发出时,就会多次调用连接的槽函数,为了保证只调一次,这里做一控制。
这里需要注意:Qt的帮助有说:
| downloadRequested(WebEngineDownloadItem download)
| This signal is emitted whenever a download has been triggered. The download argument holds |the state of the download. The download has to be explicitly accepted with |WebEngineDownloadItem::accept() or the download will be cancelled by default.
即:在下载请求转让我们对应的槽函数onDownloadRequested中后,必须设置download.accept();才表示我们接受下载请求,否则表示我们拒绝下载。
做完以上工作后,我们就可以将网上的图片和文件下载到本地了(默认下载路径为用户的系统下载目录)。
var name = arr[arr.length-1];
download.path = "E:/Qt_Test/"+name;
这样,就将默认的下载路径改变为我们自己的"E:/Qt_Test/"目录下了。
(2)我们想要获取下载的进度,怎么办?对downloadRequested信号所对应的槽函数onDownloadRequested所带的参数WebEngineDownloadItem进行查看帮助,我们能发现其有两个属性 receivedBytes:int 和 totalBytes:int 属性,通过这两个属性,我们就能够计算出下载进度了^_^。但是问题来了,我们怎样才能够实时的去接收这两个属性的变化值呢?由于信号只连接一次,因此不能够让信号多次连接来更新这两个属性值,经过搜索资料以及查看Qt帮助,我们发现,当接收到downloadRequested信号转入对应槽onDownloadRequested以后,只要我们记住这个槽携带的参数,实时读取这个参数的值,就可以更新进度了(个人猜测这个传入的参数是引用或指针,Qt在帮助中应该告诉开发者的,否则很难想通的,如果不查看他的demo和帮助,也很少有人想到这里的),因此设置了一个全局属性property var downloads;来记住这个值,然后启用定时器通过downloads对界面进行更新,这样,就达到了对下载进度的显示^_^。
话不多说,先奉上【干货代码】,再奉上【效果图】,最后有【深度解析】。
【干货代码】如下:
import QtQuick 2.4import QtQuick.Layouts 1.2import QtQuick.Controls 1.4import QtQuick.Controls.Styles 1.4import QtQuick.Window 2.2import QtWebEngine 1.2QtObject { id: windowParent property bool isInit: true // Create the initial browsing windows and open the startup page. Component.onCompleted: { var firstWindow = windowComponent.createObject(windowParent) firstWindow.webView.url = "https://www.baidu.com" } property Component windowComponent: Window { // Destroy on close to release the Window's QML resources. // Because it was created with a parent, it won't be garbage-collected. id: wnd onClosing: destroy(); visible: true width: 800 height: 600 property var downloads; property QtObject defaultProfile: WebEngineProfile { storageName: "Default" } property WebEngineView webView: webView_ WebEngineView { id: webView_ anchors.fill: parent // Handle the signal. Dynamically create the window and // use its WebEngineView as the destination of our request. onNewViewRequested: { var newWindow = windowComponent.createObject(windowParent) request.openIn(newWindow.webView) if (windowParent.isInit) { profile.downloadRequested.connect(newWindow.onDownloadRequested) profile.downloadFinished.connect(newWindow.onDownloadFinished) windowParent.isInit = false; } } } Rectangle { id: downloadView visible: false width: parent.width - 100 height: 20 color: "green" anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter property real progress_val; Rectangle { id: progress_complete color: "red" anchors.left: parent.left width: parent.width*downloadView.progress_val height: parent.height } Label { anchors.left: progress_complete.right anchors.leftMargin: 10 anchors.verticalCenter: progress_complete.verticalCenter text:parseInt(downloadView.progress_val*100) + "%" font.bold: true color: "red" } } Timer { id: reloadTimer interval: 10 running: false repeat: true onTriggered: { downloadView.progress_val = downloads.receivedBytes / downloads.totalBytes } } function onDownloadRequested(download) { downloadView.visible = true downloadView.progress_val = download.receivedBytes / download.totalBytes var arr = download.path.split('/'); var name = arr[arr.length-1]; download.path = "E:/Qt_Test/"+name; downloads = download; console.log("download->path=", download.path); reloadTimer.start(); reloadTimer.running = true; wnd.width = 300; wnd.height = 130; download.accept(); } function onDownloadFinished(download){ console.log("onDownloadFinished") reloadTimer.stop(); reloadTimer.running = false; if (download.state === 2) { downloadView.progress_val = 1.0; } downloadView.visible = false; wnd.close(); } }}以上为核心代码,接下来奉上运行【效果图】:
【深度解析】:
相比开发简单浏览器,要支持下载,必须要给WebEngineView设置profile属性,而profile属性即为WebEngineProfile,查看Qt帮助,对WebEngineView有如下两个信号
所以,当给WebEngineView设置了profile属性后,当WebEngineProfile发送downloadRequested信号时,我们就可以转入到我们自己的函数中,涉及到信号与槽,就必须对信号槽进行连接,因此,在打开新页面初次,我们添加了如下代码:
if (windowParent.isInit) {
profile.downloadRequested.connect(newWindow.onDownloadRequested)
profile.downloadFinished.connect(newWindow.onDownloadFinished)
windowParent.isInit = false;
}
将发送下载请求信号和下载完成信号与对应的槽函数进行连接。至于为什么要用windowParent.isInit进行控制,大家都知道,Qt中如果信号和槽连接多次,那么当信号发出时,就会多次调用连接的槽函数,为了保证只调一次,这里做一控制。
这里需要注意:Qt的帮助有说:
| downloadRequested(WebEngineDownloadItem download)
| This signal is emitted whenever a download has been triggered. The download argument holds |the state of the download. The download has to be explicitly accepted with |WebEngineDownloadItem::accept() or the download will be cancelled by default.
即:在下载请求转让我们对应的槽函数onDownloadRequested中后,必须设置download.accept();才表示我们接受下载请求,否则表示我们拒绝下载。
做完以上工作后,我们就可以将网上的图片和文件下载到本地了(默认下载路径为用户的系统下载目录)。
接下来介绍一些优化项:
(1)下载的图片只能下载到用户的系统下载目录吗?不,我们要自己设置自己的下载路径,因此,这里就需要对downloadRequested信号所对应的槽函数onDownloadRequested所带的参数WebEngineDownloadItem进行设置,如下:
var arr = download.path.split('/');var name = arr[arr.length-1];
download.path = "E:/Qt_Test/"+name;
这样,就将默认的下载路径改变为我们自己的"E:/Qt_Test/"目录下了。
(2)我们想要获取下载的进度,怎么办?对downloadRequested信号所对应的槽函数onDownloadRequested所带的参数WebEngineDownloadItem进行查看帮助,我们能发现其有两个属性 receivedBytes:int 和 totalBytes:int 属性,通过这两个属性,我们就能够计算出下载进度了^_^。但是问题来了,我们怎样才能够实时的去接收这两个属性的变化值呢?由于信号只连接一次,因此不能够让信号多次连接来更新这两个属性值,经过搜索资料以及查看Qt帮助,我们发现,当接收到downloadRequested信号转入对应槽onDownloadRequested以后,只要我们记住这个槽携带的参数,实时读取这个参数的值,就可以更新进度了(个人猜测这个传入的参数是引用或指针,Qt在帮助中应该告诉开发者的,否则很难想通的,如果不查看他的demo和帮助,也很少有人想到这里的),因此设置了一个全局属性property var downloads;来记住这个值,然后启用定时器通过downloads对界面进行更新,这样,就达到了对下载进度的显示^_^。
至此,QML开发浏览并器支持下载功能基本实现了,接下来就是美化和优化界面的事了,这里就不一一细细道来。
1 0
- Qt/QML开发支持下载的简单浏览器
- QML开发简单浏览器(加载H5)
- 用Qt开发简单的浏览器(一)
- 用Qt开发简单的浏览器(二)
- java swing开发最简单的浏览器源代码下载
- Qt Quick学习---------------构建一个简单的qml程序
- Qt用qml实现简单的粒子效果
- Qt用qml实现简单的粒子效果
- Qt用QML调用Android的摄像头简单示例
- Qt Quick学习---------------构建一个简单的qml程序
- qt qml和c++交互的一个简单例子
- QT QML开发andriod应用
- 关于Qt/QML开发的相关资料的分享
- qt版本的浏览器开发
- 【Qt开发】qml页面的创建、呈现与销毁
- 【Qt开发】qml组件下拉列表的实现(二)
- 【Qt开发】qml组件下拉列表的实现(一)
- 【Qt开发】qml组件下拉列表的实现(一)
- NullPointerException:null result when primitive expected
- Injectable、Promise、Interface、使用服务
- 欢迎使用CSDN-markdown编辑器
- node.js之基本流处理模块stream
- Structural directives、再谈组件生命周期
- Qt/QML开发支持下载的简单浏览器
- OpenCV中findContours轮廓提取一个边缘只对应的一个轮廓
- mysql limit用法
- 获取时间戳
- 假后看这个问的blog
- Linux下redis安装
- P1002 过河卒
- Codeforces Gym 100623H Problem H. Holes
- 【HDU4352】XHXJ's LIS 数位DP