开发 QFutureWatcher 以改善图像加载时间的问题

Posted

技术标签:

【中文标题】开发 QFutureWatcher 以改善图像加载时间的问题【英文标题】:Problems developing QFutureWatcher to improve image loading times 【发布时间】:2015-06-19 11:56:13 【问题描述】:

我正在尝试通过 QFutureWatcher 类使用多线程加载多个图像,但我无法正确执行此操作。我的代码读取图像的 url 并将它们保存在 QVector 上。然后我将这些 QString 传递给一个函数,该函数在 QMap 对象上加载、调整大小和保存图像。代码是:

    void MainWindow::loadImages()
             mImagesLoaderfutureWatcher = new QFutureWatcher<QString>() ;
        connect(mImagesLoaderfutureWatcher, SIGNAL(finished()),this, SLOT(imageLoadingfinished()));

        QVector<QString> imagesList = mProject->getImagesFileName();

        // Start the computation.
        mImagesLoaderfutureWatcher->setFuture(QtConcurrent::map(imagesList,addImageThumnailToMap));


    void MainWindow::addImageThumnailToMap(QString imageName)
        QSize desiredSize(100,100);
        QImage orig(mProject->getBasePath()+"/"+imageName);
        QImage scaled = orig.scaled(
                    desiredSize,
                    Qt::KeepAspectRatio,
                    Qt::SmoothTransformation);

        mMapImages->insert(imageName,scaled);
    

    void MainWindow::imageLoadingfinished()
        QMessageBox msg;
        msg.setText("Images loaded");
        msg.show();
    

我在尝试编译时收到的错误说未找到对函数“addImageThumnailToMap”的调用中的参数列表,但我认为没有必要在“QtConcurrent::map( )“ 功能。 感谢您的帮助

【问题讨论】:

我之前从未使用过QtConcurrent,但addImageThumnailToMap 方法可能需要(const?)传递引用而不是传递值 addImageThumnailToMap 不应该是静态的吗? 【参考方案1】:

这是因为函数是类的成员。你应该这样称呼它:

mImagesLoaderfutureWatcher->setFuture(
   QtConcurrent::map(imagesList,&MainWindow::addImageThumnailToMap));

看起来 QtConcurrent::map 只接受全局函数或静态函数,因为没有指向实例的指针来调用addImageThumnailToMap。所以将MainWindow::addImageThumnailToMap 清除为静态。

我个人更喜欢使用QtConcurrent::run,它可以处理类成员函数。例如:

void ImageGroupView::setImages( QStringList il )

    //QFuture<int> _imageLoader;    
    //QFutureWatcher<int> _watcher;
    _imageLoader = QtConcurrent::run(this, &ImageGroupView::loadImages, il );   
    connect(&_watcher, SIGNAL(finished()), this, SLOT(processImagesReady()));
    _watcher.setFuture( _imageLoader );

模板参数恰好是int,因为函数loadImages返回的是实际加载的图片数量。

int ImageGroupView::loadImages( QStringList il )

    int numLoaded=0;
    _images.clear();
    foreach ( QString img, il )
    
        if( QFileInfo( img ).exists() )
        
            _imageList.append( QImage( img ).scaled(640,480) );
            numLoaded++;
        
    
    return numLoaded;

【讨论】:

以上是关于开发 QFutureWatcher 以改善图像加载时间的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何改善 UITableview 中的加载图像?

改善三个js加载时间

Qt多线程:QtConcurrent + QFuture + QFutureWatcher

如何设置图像大小以改善 OCR 输出。?

如何使用 PyTesseract 去除图像噪声以改善结果?

阻塞 QFuture.result() 或 QFutureWatcher.waitForFinished();