C++/Qt/QNetworkAccessManager
Download from URL
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- include <QCoreApplication>
- include <QFile>
- include <QFileInfo>
- include <QList>
- include <QNetworkAccessManager>
- include <QNetworkRequest>
- include <QNetworkReply>
- include <QStringList>
- include <QTimer>
- include <QUrl>
- include <stdio.h>
class DownloadManager: public QObject {
Q_OBJECT QNetworkAccessManager manager; QList<QNetworkReply *> currentDownloads;
public:
DownloadManager(); void doDownload(const QUrl &url); QString saveFileName(const QUrl &url); bool saveToDisk(const QString &filename, QIODevice *data);
public slots:
void execute(); void downloadFinished(QNetworkReply *reply);
}; DownloadManager::DownloadManager() {
connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*)));
} void DownloadManager::doDownload(const QUrl &url) {
QNetworkRequest request(url); QNetworkReply *reply = manager.get(request); currentDownloads.append(reply);
} QString DownloadManager::saveFileName(const QUrl &url) {
QString path = url.path(); QString basename = QFileInfo(path).fileName(); if (basename.isEmpty()) basename = "download"; if (QFile::exists(basename)) { // already exists, don"t overwrite int i = 0; basename += "."; while (QFile::exists(basename + QString::number(i))) ++i; basename += QString::number(i); } return basename;
} bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data) {
QFile file(filename); if (!file.open(QIODevice::WriteOnly)) { fprintf(stderr, "Could not open %s for writing: %s\n", qPrintable(filename), qPrintable(file.errorString())); return false; } file.write(data->readAll()); file.close(); return true;
} void DownloadManager::execute() {
QStringList args = QCoreApplication::instance()->arguments(); args.takeFirst(); // skip the first argument, which is the program"s name if (args.isEmpty()) { printf("Qt Download example - downloads all URLs in parallel\n" "Usage: download url1 [url2... urlN]\n" "\n" "Downloads the URLs passed in the command-line to the local directory\n" "If the target file already exists, a .0, .1, .2, etc. is appended to\n" "differentiate.\n"); QCoreApplication::instance()->quit(); return; } foreach (QString arg, args) { QUrl url = QUrl::fromEncoded(arg.toLocal8Bit()); doDownload(url); }
} void DownloadManager::downloadFinished(QNetworkReply *reply) {
QUrl url = reply->url(); if (reply->error()) { fprintf(stderr, "Download of %s failed: %s\n", url.toEncoded().constData(), qPrintable(reply->errorString())); } else { QString filename = saveFileName(url); if (saveToDisk(filename, reply)) printf("Download of %s succeded (saved to %s)\n", url.toEncoded().constData(), qPrintable(filename)); } currentDownloads.removeAll(reply); reply->deleteLater(); if (currentDownloads.isEmpty()) // all downloads finished QCoreApplication::instance()->quit();
} int main(int argc, char **argv) {
QCoreApplication app(argc, argv); DownloadManager manager; QTimer::singleShot(0, &manager, SLOT(execute())); app.exec();
}
- include "main.moc"
</source>
Download manager
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- ifndef TEXTPROGRESSBAR_H
- define TEXTPROGRESSBAR_H
- include <QString>
class TextProgressBar { public:
TextProgressBar(); void clear(); void update(); void setMessage(const QString &message); void setStatus(qint64 value, qint64 maximum);
private:
QString message; qint64 value; qint64 maximum; int iteration;
};
- endif
- include "textprogressbar.h"
- include <QByteArray>
- include <stdio.h>
TextProgressBar::TextProgressBar()
: value(0), maximum(-1), iteration(0)
{ } void TextProgressBar::clear() {
printf("\n"); fflush(stdout); iteration = 0; value = 0; maximum = -1;
} void TextProgressBar::update() {
++iteration; if (maximum > 0) { // we know the maximum // draw a progress bar int percent = value * 100 / maximum; int hashes = percent / 2; QByteArray progressbar(hashes, "#"); if (percent % 2) progressbar += ">"; printf("\r[%-50s] %3d%% %s ", progressbar.constData(), percent, qPrintable(message)); } else { // we don"t know the maximum, so we can"t draw a progress bar int center = (iteration % 48) + 1; // 50 spaces, minus 2 QByteArray before(qMax(center - 2, 0), " "); QByteArray after(qMin(center + 2, 50), " "); printf("\r[%s###%s] %s ", before.constData(), after.constData(), qPrintable(message)); }
} void TextProgressBar::setMessage(const QString &m) {
message = m;
} void TextProgressBar::setStatus(qint64 val, qint64 max) {
value = val; maximum = max;
}
- ifndef DOWNLOADMANAGER_H
- define DOWNLOADMANAGER_H
- include <QFile>
- include <QObject>
- include <QQueue>
- include <QTime>
- include <QUrl>
- include <QNetworkAccessManager>
- include "textprogressbar.h"
class DownloadManager: public QObject {
Q_OBJECT
public:
DownloadManager(QObject *parent = 0); void append(const QUrl &url); void append(const QStringList &urlList); QString saveFileName(const QUrl &url);
signals:
void finished();
private slots:
void startNextDownload(); void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); void downloadFinished(); void downloadReadyRead();
private:
QNetworkAccessManager manager; QQueue<QUrl> downloadQueue; QNetworkReply *currentDownload; QFile output; QTime downloadTime; TextProgressBar progressBar; int downloadedCount; int totalCount;
};
- endif
- include "downloadmanager.h"
- include <QFileInfo>
- include <QNetworkRequest>
- include <QNetworkReply>
- include <QString>
- include <QStringList>
- include <QTimer>
- include <stdio.h>
DownloadManager::DownloadManager(QObject *parent)
: QObject(parent), downloadedCount(0), totalCount(0)
{ } void DownloadManager::append(const QStringList &urlList) {
foreach (QString url, urlList) append(QUrl::fromEncoded(url.toLocal8Bit())); if (downloadQueue.isEmpty()) QTimer::singleShot(0, this, SIGNAL(finished()));
} void DownloadManager::append(const QUrl &url) {
if (downloadQueue.isEmpty()) QTimer::singleShot(0, this, SLOT(startNextDownload())); downloadQueue.enqueue(url); ++totalCount;
} QString DownloadManager::saveFileName(const QUrl &url) {
QString path = url.path(); QString basename = QFileInfo(path).fileName(); if (basename.isEmpty()) basename = "download"; if (QFile::exists(basename)) { // already exists, don"t overwrite int i = 0; basename += "."; while (QFile::exists(basename + QString::number(i))) ++i; basename += QString::number(i); } return basename;
} void DownloadManager::startNextDownload() {
if (downloadQueue.isEmpty()) { printf("%d/%d files downloaded successfully\n", downloadedCount, totalCount); emit finished(); return; } QUrl url = downloadQueue.dequeue(); QString filename = saveFileName(url); output.setFileName(filename); if (!output.open(QIODevice::WriteOnly)) { fprintf(stderr, "Problem opening save file "%s" for download "%s": %s\n", qPrintable(filename), url.toEncoded().constData(), qPrintable(output.errorString())); startNextDownload(); return; // skip this download } QNetworkRequest request(url); currentDownload = manager.get(request); connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)), SLOT(downloadProgress(qint64,qint64))); connect(currentDownload, SIGNAL(finished()), SLOT(downloadFinished())); connect(currentDownload, SIGNAL(readyRead()), SLOT(downloadReadyRead())); // prepare the output printf("Downloading %s...\n", url.toEncoded().constData()); downloadTime.start();
} void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
progressBar.setStatus(bytesReceived, bytesTotal); // calculate the download speed double speed = bytesReceived * 1000.0 / downloadTime.elapsed(); QString unit; if (speed < 1024) { unit = "bytes/sec"; } else if (speed < 1024*1024) { speed /= 1024; unit = "kB/s"; } else { speed /= 1024*1024; unit = "MB/s"; } progressBar.setMessage(QString::fromLatin1("%1 %2") .arg(speed, 3, "f", 1).arg(unit)); progressBar.update();
} void DownloadManager::downloadFinished() {
progressBar.clear(); output.close(); if (currentDownload->error()) { // download failed fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString())); } else { printf("Succeeded.\n"); ++downloadedCount; } currentDownload->deleteLater(); startNextDownload();
} void DownloadManager::downloadReadyRead() {
output.write(currentDownload->readAll());
}
- include <QCoreApplication>
- include <QStringList>
- include "downloadmanager.h"
- include <stdio.h>
int main(int argc, char **argv) {
QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); arguments.takeFirst(); // remove the first argument, which is the program"s name if (arguments.isEmpty()) { printf("Qt Download example\n" "Usage: downloadmanager url1 [url2... urlN]\n" "\n" "Downloads the URLs passed in the command-line to the local directory\n" "If the target file already exists, a .0, .1, .2, etc. is appended to\n" "differentiate.\n"); return 0; } DownloadManager manager; manager.append(arguments); QObject::connect(&manager, SIGNAL(finished()), &app, SLOT(quit())); app.exec();
}
</source>
QNetworkAccessManager based google suggest
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- ifndef GOOGLESUGGEST_H
- define GOOGLESUGGEST_H
- include <QObject>
- include <QNetworkAccessManager>
QT_BEGIN_NAMESPACE class QLineEdit; class QNetworkReply; class QTimer; class QTreeWidget; QT_END_NAMESPACE class GSuggestCompletion : public QObject {
Q_OBJECT
public:
GSuggestCompletion(QLineEdit *parent = 0); ~GSuggestCompletion(); bool eventFilter(QObject *obj, QEvent *ev); void showCompletion(const QStringList &choices, const QStringList &hits);
public slots:
void doneCompletion(); void preventSuggest(); void autoSuggest(); void handleNetworkData(QNetworkReply *networkReply);
private:
QLineEdit *editor; QTreeWidget *popup; QTimer *timer; QNetworkAccessManager networkManager;
};
- endif // GOOGLESUGGEST_H
- include <QtCore>
- include <QtGui>
- include <QtNetwork>
- include "googlesuggest.h"
- define GSUGGEST_URL "http://google.com/complete/search?output=toolbar&q=%1"
GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), editor(parent) {
popup = new QTreeWidget; popup->setColumnCount(2); popup->setUniformRowHeights(true); popup->setRootIsDecorated(false); popup->setEditTriggers(QTreeWidget::NoEditTriggers); popup->setSelectionBehavior(QTreeWidget::SelectRows); popup->setFrameStyle(QFrame::Box | QFrame::Plain); popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); popup->header()->hide(); popup->installEventFilter(this); popup->setMouseTracking(true); connect(popup, SIGNAL(itemClicked(QTreeWidgetItem*, int)), SLOT(doneCompletion())); popup->setWindowFlags(Qt::Popup); popup->setFocusPolicy(Qt::NoFocus); popup->setFocusProxy(parent); timer = new QTimer(this); timer->setSingleShot(true); timer->setInterval(500); connect(timer, SIGNAL(timeout()), SLOT(autoSuggest())); connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start())); connect(&networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleNetworkData(QNetworkReply*)));
} GSuggestCompletion::~GSuggestCompletion() {
delete popup;
} bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev) {
if (obj != popup) return false; if (ev->type() == QEvent::MouseButtonPress) { popup->hide(); editor->setFocus(); return true; } if (ev->type() == QEvent::KeyPress) { bool consumed = false; int key = static_cast<QKeyEvent*>(ev)->key(); switch (key) { case Qt::Key_Enter: case Qt::Key_Return: doneCompletion(); consumed = true; case Qt::Key_Escape: editor->setFocus(); popup->hide(); consumed = true; case Qt::Key_Up: case Qt::Key_Down: case Qt::Key_Home: case Qt::Key_End: case Qt::Key_PageUp: case Qt::Key_PageDown: break; default: editor->setFocus(); editor->event(ev); popup->hide(); break; } return consumed; } return false;
} void GSuggestCompletion::showCompletion(const QStringList &choices, const QStringList &hits) {
if (choices.isEmpty() || choices.count() != hits.count()) return; const QPalette &pal = editor->palette(); QColor color = pal.color(QPalette::Disabled, QPalette::WindowText); popup->setUpdatesEnabled(false); popup->clear(); for (int i = 0; i < choices.count(); ++i) { QTreeWidgetItem * item; item = new QTreeWidgetItem(popup); item->setText(0, choices[i]); item->setText(1, hits[i]); item->setTextAlignment(1, Qt::AlignRight); item->setTextColor(1, color); } popup->setCurrentItem(popup->topLevelItem(0)); popup->resizeColumnToContents(0); popup->resizeColumnToContents(1); popup->adjustSize(); popup->setUpdatesEnabled(true); int h = popup->sizeHintForRow(0) * qMin(7, choices.count()) + 3; popup->resize(popup->width(), h); popup->move(editor->mapToGlobal(QPoint(0, editor->height()))); popup->setFocus(); popup->show();
} void GSuggestCompletion::doneCompletion() {
timer->stop(); popup->hide(); editor->setFocus(); QTreeWidgetItem *item = popup->currentItem(); if (item) { editor->setText(item->text(0)); QKeyEvent *e; e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); QApplication::postEvent(editor, e); e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier); QApplication::postEvent(editor, e); }
} void GSuggestCompletion::preventSuggest() {
timer->stop();
} void GSuggestCompletion::autoSuggest() {
QString str = editor->text(); QString url = QString(GSUGGEST_URL).arg(str); networkManager.get(QNetworkRequest(QString(url)));
} void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply) {
QUrl url = networkReply->url(); if (!networkReply->error()) { QStringList choices; QStringList hits; QString response(networkReply->readAll()); QXmlStreamReader xml(response); while (!xml.atEnd()) { xml.readNext(); if (xml.tokenType() == QXmlStreamReader::StartElement) if (xml.name() == "suggestion") { QStringRef str = xml.attributes().value("data"); choices << str.toString(); } if (xml.tokenType() == QXmlStreamReader::StartElement) if (xml.name() == "num_queries") { QStringRef str = xml.attributes().value("int"); hits << str.toString(); } } showCompletion(choices, hits); } networkReply->deleteLater();
}
- ifndef SEARCHBOX_H
- define SEARCHBOX_H
- include <QLineEdit>
class GSuggestCompletion; class SearchBox: public QLineEdit {
Q_OBJECT
public:
SearchBox(QWidget *parent = 0);
protected slots:
void doSearch();
private:
GSuggestCompletion *completer;
};
- endif // SEARCHBOX_H
- include <QDesktopServices>
- include <QUrl>
- include "searchbox.h"
- include "googlesuggest.h"
- define GSEARCH_URL "http://www.google.com/search?q=%1"
SearchBox::SearchBox(QWidget *parent): QLineEdit(parent) {
completer = new GSuggestCompletion(this); connect(this, SIGNAL(returnPressed()), SLOT(doSearch())); setWindowTitle("Search with Google"); adjustSize(); resize(400, height()); setFocus();
} void SearchBox::doSearch() {
completer->preventSuggest(); QString url = QString(GSEARCH_URL).arg(text()); QDesktopServices::openUrl(QUrl(url));
}
- include <QApplication>
- include "searchbox.h"
int main(int argc, char * argv[]) {
QApplication app(argc, argv); SearchBox *searchEdit = new SearchBox; searchEdit->show(); return app.exec();
}
</source>