Add NewClosure overload for QFuture

This commit is contained in:
John Maguire 2015-11-26 18:34:41 +00:00
parent bcaa9e4a37
commit 2cd15ff430
3 changed files with 26 additions and 21 deletions

View File

@ -22,6 +22,8 @@
#include <functional>
#include <memory>
#include <QFuture>
#include <QFutureWatcher>
#include <QMetaMethod>
#include <QObject>
#include <QSharedPointer>
@ -189,13 +191,22 @@ _detail::ClosureBase* NewClosure(QObject* sender, const char* signal,
return NewClosure(sender, signal, std::bind(callback, receiver, args...));
}
template <typename T, typename... Args>
_detail::ClosureBase* NewClosure(QFuture<T> future, QObject* receiver,
const char* slot, const Args&... args) {
QFutureWatcher<T>* watcher = new QFutureWatcher<T>;
watcher->setFuture(future);
QObject::connect(watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()));
return NewClosure(watcher, SIGNAL(finished()), receiver, slot, args...);
}
void DoAfter(QObject* receiver, const char* slot, int msec);
void DoAfter(std::function<void()> callback, std::chrono::milliseconds msec);
void DoInAMinuteOrSo(QObject* receiver, const char* slot);
template <typename R, typename P>
void DoAfter(
std::function<void()> callback, std::chrono::duration<R, P> duration) {
void DoAfter(std::function<void()> callback,
std::chrono::duration<R, P> duration) {
QTimer* timer = new QTimer;
timer->setSingleShot(true);
NewClosure(timer, SIGNAL(timeout()), callback);

View File

@ -16,7 +16,6 @@
*/
#include "prettyimage.h"
#include "ui/iconloader.h"
#include <QApplication>
#include <QContextMenuEvent>
@ -24,7 +23,6 @@
#include <QDir>
#include <QFileDialog>
#include <QFuture>
#include <QFutureWatcher>
#include <QLabel>
#include <QMenu>
#include <QNetworkAccessManager>
@ -34,6 +32,9 @@
#include <QSettings>
#include <QtConcurrentRun>
#include "core/closure.h"
#include "ui/iconloader.h"
const int PrettyImage::kTotalHeight = 200;
const int PrettyImage::kReflectionHeight = 40;
const int PrettyImage::kImageHeight =
@ -60,8 +61,9 @@ void PrettyImage::LazyLoad() {
// Start fetching the image
QNetworkReply* reply = network_->get(QNetworkRequest(url_));
connect(reply, SIGNAL(finished()), SLOT(ImageFetched()));
state_ = State_Fetching;
NewClosure(reply, SIGNAL(finished()), this,
SLOT(ImageFetched(QNetworkReply*)), reply);
}
QSize PrettyImage::image_size() const {
@ -76,8 +78,7 @@ QSize PrettyImage::sizeHint() const {
return QSize(image_size().width(), kTotalHeight);
}
void PrettyImage::ImageFetched() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
void PrettyImage::ImageFetched(QNetworkReply* reply) {
reply->deleteLater();
QImage image = QImage::fromData(reply->readAll());
@ -90,20 +91,12 @@ void PrettyImage::ImageFetched() {
QFuture<QImage> future =
QtConcurrent::run(image_, &QImage::scaled, image_size(),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>(this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(ImageScaled()));
NewClosure(future, this, SLOT(ImageScaled(QFuture<QImage>)), future);
}
}
void PrettyImage::ImageScaled() {
QFutureWatcher<QImage>* watcher =
reinterpret_cast<QFutureWatcher<QImage>*>(sender());
if (!watcher) return;
watcher->deleteLater();
thumbnail_ = QPixmap::fromImage(watcher->result());
void PrettyImage::ImageScaled(QFuture<QImage> future) {
thumbnail_ = QPixmap::fromImage(future.result());
state_ = State_Finished;
updateGeometry();
@ -179,7 +172,7 @@ void PrettyImage::contextMenuEvent(QContextMenuEvent* e) {
if (!menu_) {
menu_ = new QMenu(this);
menu_->addAction(IconLoader::Load("zoom-in", IconLoader::Base),
menu_->addAction(IconLoader::Load("zoom-in", IconLoader::Base),
tr("Show fullsize..."), this, SLOT(ShowFullsize()));
menu_->addAction(IconLoader::Load("document-save", IconLoader::Base),
tr("Save image") + "...", this, SLOT(SaveAs()));

View File

@ -18,6 +18,7 @@
#ifndef PRETTYIMAGE_H
#define PRETTYIMAGE_H
#include <QFuture>
#include <QUrl>
#include <QWidget>
@ -56,8 +57,8 @@ signals:
void paintEvent(QPaintEvent*);
private slots:
void ImageFetched();
void ImageScaled();
void ImageFetched(QNetworkReply* reply);
void ImageScaled(QFuture<QImage> future);
private:
enum State {