Я пишу программу, которая использует QtConcurrent
начать темы. В моем случае я использую его для визуализации QGraphicsView, когда использую прокрутку мыши.
Я запускаю темы, используя следующий код:
if (future.isRunning()) {
future.cancel();
}
future = QtConcurrent::run(this,&AeVectorLayer::render, renderparams, pos);
watcher.setFuture(future);
Когда поток закончен, я ловлю сигнал finished
с QfutureWatcher
,
Это моя функция рендеринга:
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
переменная, но я не знаю, как этого избежать.
Прекратите пытаться вручную управлять памятью и вместо этого используйте умный указатель, который соответствует вашему варианту использования. Потому что вы используете Move-Unaware QFuture
Вам понадобится std::shared_ptr
, Однажды QFuture
/QFutureWatcher
s выйти за рамки, и вы не держите больше shared_ptr
экземпляры, ресурс будет удален. Так что в вашем случае ваш render
функция должна вернуть QList<std::shared_ptr<AeGraphicsItem>>
, Будьте осторожны при передаче права собственности от shared_ptr
например, QGraphicsScene
: Вы должны release
от shared_ptr
на передачу права собственности.
Обратите внимание, что ваш isRunning
проверка с последующим cancel
в корне ошибочен: будущее может быть запущено, когда вы звоните isRunning
но закончите к тому времени, когда вы позвоните cancel
, Если вы хотите отменить его, просто позвоните cancel
, Также обратите внимание, что вы не можете сознательно отменить QFuture
с возвращено QtConcurrent::run
так что то, что вы делаете, само по себе очень, очень неправильно.
Других решений пока нет …