2015-05-27 2 views
1

Я хочу быть тщательным и чистым, чтобы избежать утечек памяти и объектов.Очистка QList и QGraphicsScene во избежание утечек памяти

У меня было недоразумение, что Qt автоматически очищает объекты, выходящие за пределы области видимости, за исключением того, что указатели необходимо удалить вручную.

В моем коде у меня есть ряд QList ... Например:

void someFunction() 
{ 
    QList<int> x = QList<int>() << 0 << 0 << 0 << 0; 
    QList<QImage> y; // filled in some way 
    QList<QGraphicsScene*> s; 

    s = otherFunction(x, y); 
} 

QList<QGraphicsScene*> otherFunction(QList<int>& x, const QList<QImage>& y) 
{ 
    QList<QGraphicsScene*> s; 
    s.push_back(this->scene()); // a few times; of course there is some processing... 
    return s; 
} 

void thirdFunction() 
{ 
    QList<int> x = QList<int>() << 0 << 0 << 0 << 0; 
    QList<QImage> y; // filled in some way 
    QList<QGraphicsScene*> s; 

    s = otherFunction(x, y); 
    for (int i = 0; i < s.size(); ++i) 
    { 
     view[i]->setScene(s.at(i)); // view is a QList<QGraphicsView*> 
    } 
} 

Вызывается несколько раз, я могу увидеть память все больше (видно из диспетчера задач).

Очевидно, что когда предметы выходят из сферы действия, они не удаляются ... Я сразу же заподозрил список указателей сцены.

1) Каков наилучший способ их удаления? Будет ли

qDeleteAll(s); 

в someFunction() будет достаточно? Удалит ли он указатели сцены, а также все QGraphicItems внутри сцен? или мне нужно перебирать список сцен и удалять все элементы? Должен ли я сделать это:

for (int i = 0; i < s.size(); ++i) 
    { 
     s.at(i).clear(); 
    } // then 
    qDeleteAll(s); 

2) Мне нужно, чтобы удалить списки простых переменных (int, bool) ли?
Как насчет списков объектов, таких как QImage?

3) Я предположил, что удаление элемента со сцены удаляет его указатель. Но теперь я прочитал, что после удаления элемента со сцены его нужно удалить вручную. Так же

scene().clear(); 

удалить QGraphicItem указатели, которые были добавлены к сцене? Или нужно также удалить предметы, используя вызов delete?

4) В thirdFunction у меня есть утечка памяти? Кажется, я делаю !!
Я не могу удалить сцены, так как я устанавливаю их на представления ... но что происходит со сценами, которые уже были назначены представлениям?
Как правильно его очистить?

ответ

2

1. qDeleteAll удаляет элементы в контейнере с помощью оператора С ++ delete. Это также указано в документации Qt о QGraphicsScene деструкторе:

удаляет и удаляет все элементы из объекта сцены перед уничтожением объекта сцены

Так что достаточно позвонить qDeleteAll(s).

2. Там нет необходимости удалять списки основных или Qt типов, как QList<int> или QList<QImage> как они удаляются, когда список будет удален.

3. QGraphicsScene::clear() удаляет и удаляет все предметы со сцены. Поэтому достаточно позвонить scene().clear();. Это эквивалентно вызову:

qDeletaAll(scene()->items()); 

4. Поскольку вид не брать на себя ответственность сцены, вы должны удалить ранее назначенные сцены с использованием deleteLater():

for (int i = 0; i < s.size(); ++i) 
{ 
    view[i]->scene()->deleteLater(); 
    view[i]->setScene(s.at(i)); // view is a QList<QGraphicsView*> 
}