我尝试通过 QFutureWatcher 信号更新进度条值,如下所示:
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));
但是信号progressRangeChanged和progressValueChanged在开始时只触发一次,并且都为零。所以范围是 (0, 0),值是 0。
计算完成后,完成的信号按预期工作。
我究竟做错了什么?
============= 更新:这是我的测试示例的代码。当我写它时,我发现问题在于使用 QMap 容器。当我使用 QVector 时一切正常,但是当我使用 QMap 时,问题就出现了。是否可以使用 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();
}
====== 再次更新:对不起,我在 Qt 文档中发现进度信息仅提供给随机访问迭代器。显然 QMap 不是这样的容器。我可以改用什么类型?