1

我尝试通过 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));

但是信号progressRangeChangedprogressValueChanged在开始时只触发一次,并且都为零。所以范围是 (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 不是这样的容器。我可以改用什么类型?

4

0 回答 0