![]() |
|
|
![]()
|
|
| kapbepucm |
|
||||||||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Доброе время суток!
У меня возникла проблема проблема в вероятно неправильном использовании системы деструкторов окон. Есть такая цепочка дочерних компонентов: [окно MainWindow] -> [окно Items] -> [окно Item] У родителя может быть несколько дочерних окон, в свою очередь у дочек также есть дочерние окна. Хотелось бы сделать так, чтобы при закрытии какогото окна удалилось оно само и удалялись все его дочки. При закрытии MainWindow (при открытых дочках) вылетает ошибка сегментирования. Далее прикладываю все файлы проекта "test" test.pro
main.cpp
mainform.h
mainform.cpp
items.h
items.cpp
item.h
item.cpp
Это сообщение отредактировал(а) kapbepucm - 24.10.2013, 16:33 -------------------- (С) kapbepucm |
||||||||||||||||
|
|||||||||||||||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
А ты отладчиком пробовал вставать на деструктор основного окна?
|
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 3 Всего: 56 |
Прикалываешься? |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: нет Всего: 32 |
Тебя опередили. Qt делает это самостоятельно. Надо только parent указывать для QWidget (или для QObject). -------------------- ![]() |
|||
|
||||
| kapbepucm |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Нет, думаю я в нем и не разберусь.
Я эту конструкцию добавил, так как только model->~QSqlRelationalTableModel(); спасает от сообщений в stderr типа "QSqlDatabasePrivate::removeDatabase: connection 'my_test' is still in use, all queries will cease to work." Если это не правильно, то как правильно убить экземляр класса? (Конкретно QSqlRelationalTableModel, так как model->clear(); не отвязывается от моей QSqlDatabase)
-------------------- (С) kapbepucm |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 3 Всего: 56 |
Ты вообще не правильно используешь интерфейс. Тебе не надо хранить db. Тебе просто нужно добавить соединение посредством QSqlDatabase::addDatabase("QSQLITE","my_test"). После этого, когда тебе нужно что-то от базы, ты просто вызываешь QSqlDatabase::database("my_test"). И всё, не надо потом никаких removeDatabase и прочего. Qt об это сам позаботиться.
А в твоём случае нужно использовать
Это будет правильно с точки зрения C++, но не правильно с точки зрения использования Qt, насколько я могу судить. Никогда не вызывай деструктор явно. Это сообщение отредактировал(а) vinter - 25.10.2013, 08:58 |
|||
|
||||
| math64 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 23 Всего: 72 |
Вместо
нужно делать
а явный вызов деструктора никогда не делай. Объекты, у которых назначен parent, удаляются автоматически при удалении родителя, но порядок удаления не гарантирован. Если нужен определённый порядок удаления, удаляй вручную в деструкторе. Наример, перед удалением модели, должны быть удалены объекты её использующие - т.е. перед delete model; нужно удалить TItem вручную или TItem должен коннектиться к сигналу destroyed() модели. |
||||
|
|||||
| kapbepucm |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Спасибо, код изменил. Но проблема видимо ещё где-то осталась. Я в коде проекта попытался отрезать всё, что возможно и оставить "узкое" место. Прилагаю новые файлы.
test.pro
main.cpp
mainform.h
И так, алгоритм вызова ошибки сегментирования:
-------------------- (С) kapbepucm |
||||||
|
|||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 3 Всего: 56 |
Убери
Я не знаю как этот аттрибут работает, но, подозреваю, что он предназначен для виджетов верхнего уровня и может из-за него происходит двойное удаление. Т.е. все твои "дети" итак будут удалены: у них есть родитель для этого. Чтобы точно понять, что происходит - надо смотреть код Qt. |
|||
|
||||
| kapbepucm |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Если убрать этот атрибут, то при закрытии окна его потомки не закрываются автоматически. (Окно закрывается но продолжает висеть в памяти) Исключением является первое окно- если его закрыть убивается вся цепочка детей. Зато ошибки сегментирования нет. Видимо, дополнительно надо по примеру math64 посылать "суицидальный" сигнал потомку. Как это сделать проще всего?
Это сообщение отредактировал(а) kapbepucm - 25.10.2013, 11:42 -------------------- (С) kapbepucm |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 3 Всего: 56 |
Не нужно гадать, нужно разбираться в проблеме. Скорее всего это поведение связано с Qt::Window, т.к. это обычно атрибут независимого окна, а не дочернего. Видимо с этим данное поведение и связано. Зачем тебе этот атрибут? А если нужен, то зачем тебе родители? Ну а если всё нужно, то у виджетов есть close() слот. При создании потомка подсоединяй к этом слоту некий сигнал, который и вызывай(emit) из closeEvent родителя. Но, по моему проще в этом случае создавать детей без родителя и в closeEvent() делать close() дочернему окну, за которым будет следовать delete.
|
|||
|
||||
| kapbepucm |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 993 Регистрация: 14.6.2007 Где: Латвия Репутация: нет Всего: 12 |
Я сделал по алгоритму vinter, то есть
Это сообщение отредактировал(а) kapbepucm - 29.10.2013, 17:18 -------------------- (С) kapbepucm |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 3 Всего: 56 |
Потому что твое главное окно не является указателем
Добавлено через 2 минуты и 7 секунд Вообще, мне не нравится когда объект сам себе посылает deleteLater() это должно делать ответственное лицо(родитель, например), но тебе виднее, конечно. |
|||
|
||||
![]()
|
| Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |