实现了什么功能
异步下载
用到的知识点
qsizetype
std::optional,为空会返回std::nullopt;
网络请求
QFutureWatcher: 使用信号槽monitoring a QFuture
1
2
QFuture<int> future = QtConcurrent::run(...);#run返回的future不能cancel,
watcher.setFuture(future);开始watching
部分源码解析
主要功能都在process和cancel函数里面
如何删除QGridLayout里面的元素。
1
2
3
child->widget()->setParent(nullptr);
delete child->widget();
delete child;
QFuture
函数里面new了一个QPromise,并start(),QPromise provides a way to store computation results to be accessed by QFuture
逻辑在QtFuture::connect里处理,如promise->addResult,并报告结束promise->finish();
最后用promise->future()返回
这个返回值可以调用cancel()取消异步操作,或调用then进行链式处理(如下载完成后执行缩放)并且可以使用多个then。注意lambda里面使用了(auto)。
中止下载就用reply->abort();
1
2
connect(&scalingWatcher, &QFutureWatcher<QList<QImage>>::finished, this, &Images::scaleFinished);# scalingWatcher用于监视一个异步操作的完成状态
scalingWatcher 需要先通过setFuture设置好。最后通过scalingWatcher.result()拿结果。
其它:
qDeleteAll(ui->urlListWidget->selectedItems(); # qDeleteAll() 用于删除给定容器中的所有元素。
image.loadFromData(imgData);加载图片数据
注意如果为空,会返回std::nullopt;不会继续遍历。
同时注意使用了QSharedPointer,因为多处用到。
5.15里面同名示例:
1
2
3
4
5
6
QFutureWatcher<QImage> *imageScaling = new QFutureWatcher<QImage>(this);
它有resultReadyAt和finished信号,有cancel槽,有暂停和恢复槽 togglePaused
imageScaling->setFuture(QtConcurrent::mapped(files, scale));//scale是一个函数
QPixmap::fromImage(imageScaling->resultAt(num))// 取结果
通过Qt Concurrent,不需要使用底层的mutex,读写锁等api就可以写多线程程序.
参考
https://doc.qt.io/qt-6/qtconcurrent-imagescaling-example.html