开发 QFutureWatcher 以改善图像加载时间的问题
Problems developing QFutureWatcher to improve image loading times
我正在尝试通过 QFutureWatcher class 使用多线程加载多个图像,但我无法正确执行。我的代码读取图像的 url 并将它们保存在 QVector 上。然后我将这些 QStrings 传递给一个函数,该函数加载、调整图像大小并将图像保存在 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()" 函数。
感谢您的帮助
因为函数是class的成员。你应该这样称呼它:
mImagesLoaderfutureWatcher->setFuture(
QtConcurrent::map(imagesList,&MainWindow::addImageThumnailToMap));
它看起来也像 QtConcurrent::map 只接受全局函数或静态函数,因为没有指向实例的指针来调用 addImageThumnailToMap
。所以 declear MainWindow::addImageThumnailToMap
为静态。
我个人比较喜欢用QtConcurrent::run
,可以处理class个成员函数。例如:
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 returns实际加载图片的数量。
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 class 使用多线程加载多个图像,但我无法正确执行。我的代码读取图像的 url 并将它们保存在 QVector 上。然后我将这些 QStrings 传递给一个函数,该函数加载、调整图像大小并将图像保存在 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()" 函数。 感谢您的帮助
因为函数是class的成员。你应该这样称呼它:
mImagesLoaderfutureWatcher->setFuture(
QtConcurrent::map(imagesList,&MainWindow::addImageThumnailToMap));
它看起来也像 QtConcurrent::map 只接受全局函数或静态函数,因为没有指向实例的指针来调用 addImageThumnailToMap
。所以 declear MainWindow::addImageThumnailToMap
为静态。
我个人比较喜欢用QtConcurrent::run
,可以处理class个成员函数。例如:
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 returns实际加载图片的数量。
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;
}