I try to update progress bar value by QFutureWatcher signals like this:
QObject::connect(
&imageCreating_, &QFutureWatcher<void>::finished,
loader, &Loader::creatingImagesFinished
);
QObject::connect(
&imageCreating_, &QFutureWatcher<void>::progressRangeChanged,
loader, &Loader::setRange
);
QObject::connect(
&imageCreating_, &QFutureWatcher<void>::progressValueChanged,
loader, &Loader::setValue
);
imageCreating_.setFuture(QtConcurrent::map(items_, updateImage));
But signals progressRangeChanged and progressValueChanged fire only once at the beginning and both are zero. So range is (0, 0) and value is 0.
Finished signal works as expected when the computation is complete.
What am I doing wrong?
============= updated: Here is the code of my test example. When I wrote it I found that problem is in using QMap container. When I'm using QVector all works fine, but when I'm using QMap the problem has occur. Is it possible to get progress values using QMap?
#include <QtWidgets>
#include <QtConcurrent>
using namespace QtConcurrent;
typedef struct {
/*....*/
QImage* image;
} Item;
void burnTextImage(Item& item)
{
QImage* img = new QImage("D:/Projects/Sortition/res/img/document260x195.png");
QPainter p (img);
p.drawText(QRect(10, 10, 200, 145), "some text");
item.image = img;
}
void spin(int &iteration)
{
const int work = 9999999;
volatile int v = 0;
for (int j = 0; j < work; ++j)
++v;
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMap<int, Item> items_;
//QVector<Item> items_;
//QVector<int> vector;
for (int i = 0; i < 20000; ++i) {
Item item;
item.image = 0;
items_.insert(i, item);
//items_.append(item);
//vector.append(i);
}
QProgressDialog dialog;
dialog.setLabelText(QString("Progressing using %1 thread(s)...").arg(QThread::idealThreadCount()));
QFutureWatcher<void> imageCreating_;
QObject::connect(&imageCreating_, SIGNAL(finished()), &dialog, SLOT(reset()));
QObject::connect(&dialog, SIGNAL(canceled()), &imageCreating_, SLOT(cancel()));
QObject::connect(&imageCreating_, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
QObject::connect(&imageCreating_, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));
imageCreating_.setFuture(QtConcurrent::map(items_, burnTextImage));
//imageCreating_.setFuture(QtConcurrent::map(vector, spin));
dialog.exec();
imageCreating_.waitForFinished();
qDebug() << "Canceled?" << imageCreating_.future().isCanceled();
}
====== updaited again: I'm sorry, I found in Qt documentation that progress information is provided only for random access iterator. Clearly that QMap is not such container. What type I can use instead?