Can my QWebView (or another class) trap a user's "save as" on the web page itself?
-
I am presently using QWebView to support a custom page that a colleague has written. The page has an "Export" button that formats a PDF and sends a "save as" to the browser. If the browser is Chrome, Firefox, etc. it puts up a dialog of where to save it. I need to do the same within my Qt application. I do see a "downloadRequested" signal and have implemented it, but my slot is never invoked, suggesting that the signal is incorrect.
Thank you,
Andy -
Hi,
Can you post your code please?
Not sure to understand "I do see a "downloadRequested" signal and have implemented it" part. -
Here is my code:
void patientReport::acceptScreenControl(QUrl url)
{
qDebug() << "into patientReport::acceptScreenControl: url is" << url;
connect(ui->webView->page(),SIGNAL(downloadRequested(QNetworkRequest)),this,SLOT(download(QNetworkRequest)));
ui->webView->setUrl(url);
}and the slot:
void patientReport::download(QNetworkRequest request)
{
qDebug() << "patientReport::download";
// presumably I would add the content here to get the download? But it doesn't even get called
// now so I am trying to get that far first.
} -
According to the documentation:
This signal is emitted when the user decides to download a link. The url of the link as well as additional meta-information is contained in request.
So I assume that this signal is only triggered when the user right-clicks on a link and selects "Save as". Here, correct me if I'm wrong, your page contains a button, not a link. Which means that it may not be the same signal triggered, if any signal is triggered.
-
Very nice. In fact I am now getting my slot run when the user does save as.
The next step then is to actually get the content. Is the data available through the QNetworkRequest, or does it need to be obtained somehow differently? I have reviewed the documentation and have not seen what functions may be used to get the data itself?
-
Here is what I would try to do, launch the download with the get method using the URL contained in the request, connect some signals/slots to treat the download asynchronously, ask the user the PDF file name and path, save it when download is down, clean and deal with different issue that the program may encounters.
Warning: I have not tested this code but here is the essential treatment
Add these two variables in your header file
QFile m_output; QNetworkReply* m_currentDownload;Here is the treatment in the cpp file
void patientReport::download(QNetworkRequest request) { QNetworkAccessManager manager; QNetworkRequest request(request.url()); m_currentDownload = manager.get(request); connect(m_currentDownload, SIGNAL(readyRead()), this, SLOT(downloadReadyRead())); connect(m_currentDownload, SIGNAL(finished()), this, SLOT(downloadFinished())); } void patientReport::downloadReadyRead() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::homePath(), tr("PDF (*.pdf)")); if (fileName.isEmpty()) { return; } m_output.setFileName(filename); if (!m_output.open(QIODevice::WriteOnly)) { QMessageBox::warning(this, "Open error", QString("Cannot open %1 in write mode.").arg(filename)); } m_output.write(m_currentDownload->readAll()); } void patientReport::downloadFinished() { m_output.close(); if (m_currentDownload->error()) { // download failed QMessageBox::warning(this, "Download error", QString("Failed: %1").arg(m_currentDownload->errorString())); } else { QMessageBox::success("Succeeded."); } m_currentDownload->deleteLater(); }You can find further information reading this example:
http://doc.qt.io/qt-5/qtnetwork-downloadmanager-downloadmanager-cpp.htmlThis can also be useful:
http://www.bogotobogo.com/Qt/Qt5_QNetworkRequest_Http_File_Download.php -
You're welcome!