Revamp QtConcurrent examples to C++11
I updated signals and slots and for each loops to the new syntax and replaced most free functions with std::function. Task-number: QTBUG-60641 Change-Id: I7693f81f71c7f53fcbe83189a0de2fb76ddf99a8 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
d4b3ce9a28
commit
ab9f4d5db6
@ -48,15 +48,10 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "imagescaling.h"
|
||||
|
||||
#include <qmath.h>
|
||||
|
||||
const int imageSize = 100;
|
||||
|
||||
QImage scale(const QString &imageFileName)
|
||||
{
|
||||
QImage image(imageFileName);
|
||||
return image.scaled(QSize(imageSize, imageSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
#include <functional>
|
||||
|
||||
Images::Images(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@ -65,19 +60,19 @@ Images::Images(QWidget *parent)
|
||||
resize(800, 600);
|
||||
|
||||
imageScaling = new QFutureWatcher<QImage>(this);
|
||||
connect(imageScaling, SIGNAL(resultReadyAt(int)), SLOT(showImage(int)));
|
||||
connect(imageScaling, SIGNAL(finished()), SLOT(finished()));
|
||||
connect(imageScaling, &QFutureWatcher<QImage>::resultReadyAt, this, &Images::showImage);
|
||||
connect(imageScaling, &QFutureWatcher<QImage>::finished, this, &Images::finished);
|
||||
|
||||
openButton = new QPushButton(tr("Open Images"));
|
||||
connect(openButton, SIGNAL(clicked()), SLOT(open()));
|
||||
connect(openButton, &QPushButton::clicked, this, &Images::open);
|
||||
|
||||
cancelButton = new QPushButton(tr("Cancel"));
|
||||
cancelButton->setEnabled(false);
|
||||
connect(cancelButton, SIGNAL(clicked()), imageScaling, SLOT(cancel()));
|
||||
connect(cancelButton, &QPushButton::clicked, imageScaling, &QFutureWatcher<QImage>::cancel);
|
||||
|
||||
pauseButton = new QPushButton(tr("Pause/Resume"));
|
||||
pauseButton->setEnabled(false);
|
||||
connect(pauseButton, SIGNAL(clicked()), imageScaling, SLOT(togglePaused()));
|
||||
connect(pauseButton, &QPushButton::clicked, imageScaling, &QFutureWatcher<QImage>::togglePaused);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->addWidget(openButton);
|
||||
@ -113,9 +108,11 @@ void Images::open()
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
|
||||
"*.jpg *.png");
|
||||
|
||||
if (files.count() == 0)
|
||||
if (files.isEmpty())
|
||||
return;
|
||||
|
||||
const int imageSize = 100;
|
||||
|
||||
// Do a simple layout.
|
||||
qDeleteAll(labels);
|
||||
labels.clear();
|
||||
@ -130,6 +127,11 @@ void Images::open()
|
||||
}
|
||||
}
|
||||
|
||||
std::function<QImage(const QString&)> scale = [imageSize](const QString &imageFileName) {
|
||||
QImage image(imageFileName);
|
||||
return image.scaled(QSize(imageSize, imageSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
};
|
||||
|
||||
// Use mapped to run the thread safe scale function on the files.
|
||||
imageScaling->setFuture(QtConcurrent::mapped(files, scale));
|
||||
|
||||
|
@ -57,9 +57,9 @@ class Images : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Images(QWidget *parent = 0);
|
||||
Images(QWidget *parent = nullptr);
|
||||
~Images();
|
||||
public Q_SLOTS:
|
||||
public slots:
|
||||
void open();
|
||||
void showImage(int num);
|
||||
void finished();
|
||||
|
@ -55,11 +55,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <qtconcurrentmap.h>
|
||||
|
||||
QImage scale(const QImage &image)
|
||||
{
|
||||
qDebug() << "Scaling image in thread" << QThread::currentThread();
|
||||
return image.scaled(QSize(100, 100), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
#include <functional>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -72,6 +68,12 @@ int main(int argc, char *argv[])
|
||||
for (int i = 0; i < imageCount; ++i)
|
||||
images.append(QImage(1600, 1200, QImage::Format_ARGB32_Premultiplied));
|
||||
|
||||
std::function<QImage(const QImage&)> scale = [](const QImage &image) -> QImage
|
||||
{
|
||||
qDebug() << "Scaling image in thread" << QThread::currentThread();
|
||||
return image.scaled(QSize(100, 100), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
};
|
||||
|
||||
// Use QtConcurrentBlocking::mapped to apply the scale function to all the
|
||||
// images in the list.
|
||||
QList<QImage> thumbnails = QtConcurrent::blockingMapped(images, scale);
|
||||
|
@ -51,24 +51,16 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace QtConcurrent;
|
||||
|
||||
const int iterations = 20;
|
||||
|
||||
void spin(int &iteration)
|
||||
{
|
||||
const int work = 1000 * 1000 * 40;
|
||||
volatile int v = 0;
|
||||
for (int j = 0; j < work; ++j)
|
||||
++v;
|
||||
|
||||
qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
const int iterations = 20;
|
||||
|
||||
// Prepare the vector.
|
||||
QVector<int> vector;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
@ -80,10 +72,20 @@ int main(int argc, char **argv)
|
||||
|
||||
// Create a QFutureWatcher and connect signals and slots.
|
||||
QFutureWatcher<void> futureWatcher;
|
||||
QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
|
||||
QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
|
||||
QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
|
||||
QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));
|
||||
QObject::connect(&futureWatcher, &QFutureWatcher<void>::finished, &dialog, &QProgressDialog::reset);
|
||||
QObject::connect(&dialog, &QProgressDialog::canceled, &futureWatcher, &QFutureWatcher<void>::cancel);
|
||||
QObject::connect(&futureWatcher, &QFutureWatcher<void>::progressRangeChanged, &dialog, &QProgressDialog::setRange);
|
||||
QObject::connect(&futureWatcher, &QFutureWatcher<void>::progressValueChanged, &dialog, &QProgressDialog::setValue);
|
||||
|
||||
// Our function to compute
|
||||
std::function<void(int&)> spin = [](int &iteration) {
|
||||
const int work = 1000 * 1000 * 40;
|
||||
volatile int v = 0;
|
||||
for (int j = 0; j < work; ++j)
|
||||
++v;
|
||||
|
||||
qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId();
|
||||
};
|
||||
|
||||
// Start the computation.
|
||||
futureWatcher.setFuture(QtConcurrent::map(vector, spin));
|
||||
|
@ -65,15 +65,17 @@ using namespace QtConcurrent;
|
||||
/*
|
||||
Utility function that recursivily searches for files.
|
||||
*/
|
||||
QStringList findFiles(const QString &startDir, QStringList filters)
|
||||
QStringList findFiles(const QString &startDir, const QStringList &filters)
|
||||
{
|
||||
QStringList names;
|
||||
QDir dir(startDir);
|
||||
|
||||
foreach (QString file, dir.entryList(filters, QDir::Files))
|
||||
const auto files = dir.entryList(filters, QDir::Files);
|
||||
for (const QString &file : files)
|
||||
names += startDir + '/' + file;
|
||||
|
||||
foreach (QString subdir, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot))
|
||||
const auto subdirs = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
for (const QString &subdir : subdirs)
|
||||
names += findFiles(startDir + '/' + subdir, filters);
|
||||
return names;
|
||||
}
|
||||
@ -83,17 +85,18 @@ typedef QMap<QString, int> WordCount;
|
||||
/*
|
||||
Single threaded word counter function.
|
||||
*/
|
||||
WordCount singleThreadedWordCount(QStringList files)
|
||||
WordCount singleThreadedWordCount(const QStringList &files)
|
||||
{
|
||||
WordCount wordCount;
|
||||
foreach (QString file, files) {
|
||||
for (const QString &file : files) {
|
||||
QFile f(file);
|
||||
f.open(QIODevice::ReadOnly);
|
||||
QTextStream textStream(&f);
|
||||
while (textStream.atEnd() == false)
|
||||
foreach (const QString &word, textStream.readLine().split(' '))
|
||||
while (!textStream.atEnd()) {
|
||||
const auto words = textStream.readLine().split(' ');
|
||||
for (const QString &word : words)
|
||||
wordCount[word] += 1;
|
||||
|
||||
}
|
||||
}
|
||||
return wordCount;
|
||||
}
|
||||
@ -109,9 +112,11 @@ WordCount countWords(const QString &file)
|
||||
QTextStream textStream(&f);
|
||||
WordCount wordCount;
|
||||
|
||||
while (textStream.atEnd() == false)
|
||||
foreach (const QString &word, textStream.readLine().split(' '))
|
||||
while (!textStream.atEnd()) {
|
||||
const auto words = textStream.readLine().split(' ');
|
||||
for (const QString &word : words)
|
||||
wordCount[word] += 1;
|
||||
}
|
||||
|
||||
return wordCount;
|
||||
}
|
||||
@ -137,8 +142,6 @@ int main(int argc, char** argv)
|
||||
|
||||
qDebug() << "warmup";
|
||||
{
|
||||
QTime time;
|
||||
time.start();
|
||||
WordCount total = singleThreadedWordCount(files);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user