问题
使用webe加载网页时,点击下载页面会没有反应。原因就是它默认是关闭下载功能
解决
需要在profile里监听下载事件打开onDownloadRequested
,当有下载时会触发这个信号,会获取到一个WebEngineDownloadItem
这是下载的东西,查询它的一些相关参数,可以修改路径和开始下载
import QtQuick 2.15
import QtQuick.Window 2.15
import QtWebEngine 1.9
import Qt.labs.platform 1.1
import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
property var savePath: "";
WebEngineView{
id:webview
anchors.fill:parent;
url:"https://www.kuwo.cn/down"
// 使用 WebEngineProfile 来监听下载事件
profile: WebEngineProfile {
id:webprofile
onDownloadRequested: function(downloadItem) {
//当触发下载时,onDownloadRequested 事件会被调用,接收 WebEngineDownloadItem 对象来管理下载过程。
console.log("Download requested: ", downloadItem.url)
// 使用 FileDialog 让用户选择文件路径
// folderDialog.open();
//设置下载路径,会获取电脑标准的下载路径进行拼接
var customSavePath = StandardPaths.writableLocation(StandardPaths.DownloadLocation).toString().replace("file:///", "");;
savePath = customSavePath;
console.log("Custom save path: ", customSavePath);
console.log("downloadDirectory path: ", downloadItem.downloadDirectory);
downloadItem.downloadDirectory = customSavePath;
console.log("downloadDirectory path: ", downloadItem.downloadDirectory);
downloadItem.accept();
}
onDownloadFinished: function(downloadItem){
if(downloadItem.state === WebEngineDownloadItem.DownloadCompleted){
console.log("下载成功 ");
dialogText.text = "下载成功,地址为:" + savePath;
downloadCompleteDialog.open();
}
else if(downloadItem.state === WebEngineDownloadItem.DownloadCancelled){
console.log("下载失败");
}
}
}
}
Dialog {
id: downloadCompleteDialog;
title: "下载通知";
standardButtons: Dialog.Ok;
anchors.centerIn: parent;
property var downloadItem: null;
onAccepted: {
console.log("Dialog accepted");
}
onRejected: {
console.log("Dialog closed");
}
Text {
id: dialogText;
anchors.margins: 10;
anchors.fill: parent;
text: "下载信息将在这里显示";
}
}
}
这样修改完成后,就能够进行下载
使用选择文件夹的方式下载
qml中的filedialog无法卡住程序因此无法使用,dowmITem
在onDownloadRequested
这个信号中如果不调用accept
就会销毁,外边也无法拿到,我们需要使用c++类的方式.
新建一个c++类SelectDownloadFolder
.h 把拿到文件夹的函数暴露给qml
#ifndef SELECTDOWNLOADFOLDER_H
#define SELECTDOWNLOADFOLDER_H
#include <QObject>
#include <QFileDialog>
#include <QString>
class SelectDownloadFolder : public QObject
{
Q_OBJECT
public:
explicit SelectDownloadFolder(QObject *parent = nullptr);
Q_INVOKABLE QString getSelectDownloadFolder();
signals:
};
#endif // SELECTDOWNLOADFOLDER_H
.cpp 使用c++的filedialog来打开文件夹卡住程序
#include "selectdownloadfolder.h"
SelectDownloadFolder::SelectDownloadFolder(QObject *parent)
: QObject{parent}
{}
QString SelectDownloadFolder::getSelectDownloadFolder()
{
QString savepath = QFileDialog::getExistingDirectory(
nullptr,
QString(" 选择文件夹 "),
QString(),
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
);
return savepath;
}
写完类后需要注册这个c++给qml
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "selectdownloadfolder.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
// 注册类并创建实例
qmlRegisterType<SelectDownloadFolder>("com.mycompany", 1, 0, "SelectDownloadFolder");
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
然后就可以在qml中调用,这样我们就可以拿到选择的路径,在路径选择完之后才会开始下载.
import com.mycompany 1.0
SelectDownloadFolder{
id:selectedfolder
}
savePath = selectedfolder.getSelectDownloadFolder();