crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V  < 1 2 3  
Ответить в данную темуНачать новую тему
> Корректное удаление виджета
SABROG
  опции профиля:
сообщение 25.9.2009, 10:46
Сообщение #21


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Лучше, когда этих телодвижений меньше. Code less - create more.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 25.9.2009, 19:08
Сообщение #22


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(BRE @ 24.9.2009, 22:53) *
Если сейчас выполняется твоя функция (в которой удаляется какой то объект), то это говорит о том, что процессор выполняет код этой функции, а не обрабатывает события или делает что-то еще. ;)
Цитата(BRE @ 24.9.2009, 23:38) *
А потом объекта уже не будет... Деструктор QObject уберет указатель на этот объект из списка parent (если он есть) и уничтожит его.

Объект удалится, а сообщения для этого объекта почистятся в деструкторе QObject?
Помогите тогда разобрать в таком коде

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    movie = new QMovie("post.gif", "gif", this);
    connect(movie, SIGNAL(frameChanged(int)), this, SLOT(myslot2()));
    movie->start();
}

void MyLabel::myslot2()
{
    qDebug("delete");
    delete movie;
//    movie->deleteLater();
}

В током виде приложение моментально падает, хотя из выше сказанного получается, что не должно. Если удалять через deleteLater, этого не произойдёт.

Хм...
Заменил QMovie на QTimer, затем на QPushButton - вылетов нет.
В чем проблема с QMovie?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 25.9.2009, 19:47
Сообщение #23


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Я чуть выше писал, что нельзя удалять объект из самого себя, для этого как раз подходит deleteLater.
А здесь, не явно, но именно это и происходит.
Из цикла обработки событий вызывается обработчик события таймера для объекта movie, он посылает сигнал frameChanged, это разворачивается в прямой вызов метода myslot2, из которого мы убиваем объект movie.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 25.9.2009, 20:02
Сообщение #24


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(BRE @ 25.9.2009, 23:47) *
это разворачивается в прямой вызов метода myslot2, из которого мы убиваем объект movie.
об этом я даже и не подумал
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 25.9.2009, 20:06
Сообщение #25


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Понятно.
Сколько интересно подобных объектов в Qt?
Вот и получается что удалять их через delete чревато, так как не известно как они реализованы, и к чему это приведёт. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 25.9.2009, 20:20
Сообщение #26


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(igor_bogomolov @ 25.9.2009, 21:06) *
Вот и получается что удалять их через delete чревато, так как не известно как они реализованы, и к чему это приведёт. :)

Достаточно один раз разобраться и дальше не пытаться удалять объект из слота, который инициируется сигналом этого объекта. :)

IMHO. На самом деле если бы все было так плохо с delete, то Тролли уже давно перекрыли бы оператора delete для объекта QObject, что бы он имел такое же поведение как и deleteLater.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 25.9.2009, 20:28
Сообщение #27


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Я понимаю, что я уже придираюсь, и что это ошибки проектирования. Просто на примере с QMovie это не очевидно.
Теперь и я разобрался, буду иметь в виду :)

Сообщение отредактировал igor_bogomolov - 25.9.2009, 20:30
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 25.9.2009, 20:45
Сообщение #28


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(BRE @ 25.9.2009, 20:47) *
Из цикла обработки событий вызывается обработчик события таймера для объекта movie, он посылает сигнал frameChanged, это разворачивается в прямой вызов метода myslot2, из которого мы убиваем объект movie.


А можете мне объяснить подробней, я не разобрался? Вот мы запускаем таймер тут:

movie->start();


Он срабатывает при выходе из конструктора QLabel, когда заходим в цикл событий. При первом событии таймера movie удаляется, значит вместе с ним должен удалиться и таймер и краша быть не должно... В чем подводный камень?
---
А похоже понял. Внутренний вызов из метода QMovie метода myslot2 и возврат в уже не валидный объект.

Сообщение отредактировал SABROG - 25.9.2009, 20:53
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 25.9.2009, 21:05
Сообщение #29


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(SABROG @ 25.9.2009, 21:45) *
Он срабатывает при выходе из конструктора QLabel, когда заходим в цикл событий. При первом событии таймера movie удаляется, значит вместе с ним должен удалиться и таймер и краша быть не должно... В чем подводный камень?

DirectConnectin - подразумевает прямое связывание, т.е. грубо говоря emit signal() разворачивается в функцию:
void signal()
{
    obj->slot();    
}

Из eventloop'а активируется таймер объекта movie, мы попадаем в метод _q_loadNextFrame() объекта movie (!), из него идет прямой вызов метода slot2, в котором мы убиваем объект movie. После этого начинается откат из метода slot2, должны вернуться в _q_loadNextFrame объекта movie и продолжить выполнение этого метода. А movie - убит. Приплыли.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V  < 1 2 3
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


9 чел. читают эту тему (гостей: 9, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 18.10.2024, 6:29