2

我正在编写一个QtConcurrent用于启动线程的程序。就我而言,当我使用鼠标滚动时,我使用它来呈现 QGraphicsView。

我正在使用以下代码启动线程:

if (future.isRunning()) {
    future.cancel();
}

future = QtConcurrent::run(this,&AeVectorLayer::render, renderparams, pos);
watcher.setFuture(future);

线程完成后,我finishedQfutureWatcher.

这是我的渲染功能:

QList<AeGraphicsItem*> AeVectorLayer::render(Ae::renderParams renderparams, int pos)
{
    AeVectorHandler *coso = new AeVectorHandler();
    coso->openDataset(AeLayer::absoluteFilePath);
    coso->setTransformCoordinates(myEPSG);
    QList<AeGraphicsItem*> bla = coso->getItems(renderparams.sceneRect.x(), 
    renderparams.sceneRect.y(), renderparams.sceneRect.width(), 
    renderparams.sceneRect.height(), renderparams.zoom, color, this);
    for (int i = 0; i < bla.size(); i++)
        bla.at(i)->setZValue((qreal)pos);
    delete coso;
    return bla;
}

如您所见,我的QList<QGraphicsItem*>渲染函数中有一个。当未来被取消时,我怎样才能销毁这个列表?我不明白在我的代码中我正在重新定义future变量,但我不知道如何避免它。

4

1 回答 1

1

停止尝试手动管理内存,而是使用适合您用例的智能指针。因为您使用 move-unaware QFuture,所以您需要一个std::shared_ptr. 一旦QFuture/QFutureWatcher超出范围,并且您不再持有更多shared_ptr实例,该资源将被删除。所以在你的情况下,你的render函数应该返回一个QList<std::shared_ptr<AeGraphicsItem>>. shared_ptr当您将所有权从s 转移到例如 a时要小心QGraphicsScene:您必须releaseshared_ptr所有权转移。

请注意,您isRunning随后的检查cancel存在根本缺陷:未来可能在您调用时正在运行,isRunning但在您调用时已完成cancel。如果你想取消它,只需调用cancel。另请注意,您无法有意义地取消QFuture返回的 s,QtConcurrent::run因此您所做的事情本身就是非常非常错误的。

于 2018-07-12T07:08:55.800 回答