| Summary: | Проблемы в обработке событий при удаление самого объекта. | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Sisyphus | Reporter: | Roman Savochenko <rom_as> | ||||
| Component: | qt4 | Assignee: | Sergey V Turchin <zerg> | ||||
| Status: | CLOSED FIXED | QA Contact: | qa-sisyphus | ||||
| Severity: | normal | ||||||
| Priority: | P2 | CC: | inger, mike, zerg | ||||
| Version: | unstable | ||||||
| Hardware: | all | ||||||
| OS: | Linux | ||||||
| Attachments: |
|
||||||
Created attachment 2645 [details]
Программа демонстрации проблемы
Подготовил наглядный пример этой проблемы на основе примера из дистрибутива
QT4.4 - basiclayouts. Для кнопки Button1 добавил eventFilter() c целью отлова
потери фокуса. По результату потери фокуса удаляется кнопка Button2. Так вот,
если сначала нажать кнопку Button1, а затем Button3, то кнопка Button2
корректно удалится, а вот если после Button1 нажать Button2, то программа
упадёт по этой самой проблеме.
alterator-browser-qt - X11 Qt interface driver for alterator
* Fri May 30 2008 Sergey V Turchin <zerg@altlinux> 2.9.83-alt1
- fix #15792
* Fri May 30 2008 Sergey V Turchin <zerg@altlinux> 2.9.82-alt1
- fix *listbox state-rows attribute
- force return *multi*listbox current-rows and state-rows if empty list
* Thu May 29 2008 Sergey V Turchin <zerg@altlinux> 2.9.81-alt1
Я не уверен, это бага Qt или нет, но можно использовать deleteLater Это не всегда возможно. У меня был случай с QAbstractItemView::itemDelegate() Когда я создаю в качестве элемента редактирования комбобокс(редактируемый) и добавляю ему обработку события принятия выбора по выбору элемента. Так вот, если я редактирую содержимое этого комбобокса руками и нажимаю Enter, то приходит два события и он валится поскольку сама QT удалила этот элемент после первого события. Кроме того, на динамических интерфейсах, где элементы часто создаются и удаляются это неизбежно будет и проблему просто так не обойдёшь. Похоже, в Trolltech думают, что это фича http://trolltech.net/developer/task-tracker/index_html?method=entry&id=198093 http://trolltech.de/developer/task-tracker/index_html?method=entry&id=205903 Если бы оно только писало и не падало. В приложенном примере нет моего кода, а оно устойчиво падает на банальной ситуации. Подскажите адрес официального багтрекера QT. Запощу эту багу прямо им. (In reply to comment #7) > Подскажите адрес официального багтрекера QT. Запощу эту багу прямо им. > http://trolltech.com/developer/task-tracker Остановились на deleteLater Закрываю |
Неоднократно замечены проблемы с перекрытием в обработке событий/сигналов и удаления объекта с этими обработчиками. На QT4.4 он начал предупреждать о подобном: QObject: Do not delete object, 'unnamed', during its event handler! Но не понятно другое, как это возможно в одном потоке и как это разруливать? Ситуация достаточно неочевидна и перестройкой пользовательского кода часто не лечится или лечится только путём потери функциональности. Например ситуация: - инспектор атрибутов генерирует сигнал на обновления виджета при потере фокуса; в процессе обновления удаляется вложенный виджет и вместо него создаётся новый; - в тоже время фокус теряется по причине выбора этого самого виджета (удаляемого), т.е. какие-то события пошли к нему; - в результате генерируется "QObject: Do not delete object, 'unnamed', during its event handler!" и происходит обрушение. Я не понимаю как такое может вообще происходить, разве в деструкторе не откидываются из очереди события к удаляемому виджету? Порылся в коде QT4.4 и меня насторожил вот этот участок кода в функции QCoreApplication::notifyInternal( ) файла qcoreapplication.cpp: bool returnValue; try { returnValue = notify(receiver, event); } catch(...) { --threadData->loopLevel; throw; } Получается при возникновении исключения оно передаётся на уровень выше, а флаг d->inEventHandler не очищается, что и является причиной указанного сообщения, а установка этого флага осуществляется только там. Не исключено, что не очищается ещё чего нибуть.