Russian Qt Forum
Ноябрь 24, 2024, 09:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не удалять чайлды.  (Прочитано 5295 раз)
QCasper
Гость
« : Февраль 27, 2007, 17:57 »

У меня есть QDockWidget, я ему в определенный момент делаю setWidget(widget), потом во второй определенный момент я удаляю widget. И когда завершаю работу приложения, оно сваливается, насколько я понял из-за того что док виджет пытается удалить тот виджет, а там уже все инвалидно. Как пофиксить?
Записан
Mikhail
Программист
*****
Online Online

Сообщений: 587


Просмотр профиля
« Ответ #1 : Февраль 27, 2007, 20:19 »

А кто у этого видгета parent?
В этом проблема.
Почему же QDockWidget должен удалять widget?
Скорее всего ты создаешь widget типа new MyWidget(this).
Вот this == parent и пытается в своем деструкторе по умолчанию удалить уже удаленныый widget.
Записан
QCasper
Гость
« Ответ #2 : Февраль 27, 2007, 21:13 »

Цитата: "Mikhail"
А кто у этого видгета parent?
В этом проблема.
Почему же QDockWidget должен удалять widget?
Скорее всего ты создаешь widget типа new MyWidget(this).
Вот this == parent и пытается в своем деструкторе по умолчанию удалить уже удаленныый widget.


А я разве спорю? Парент у этого виджета - док виджет, он его и пытается удалить, я вроде так и написал. Вопрос не в том че за фигня, а в том как сделать чтобы этого не происходило. Как сделат чтобы парент не удалял этот виджет, даже не пытался. Если я что-то непонятное говорю, то вот код:

Код:
QDockWidget *dock = new QDockWidget;
QWidget *widget = new QWidget(dock);
dock->setWidget(widget);


После всего этого, widget в определенный момент удаляется. И соотвественно приложение падает когда деструктор доквиджета пытается замочить этот виджет.
Записан
Lion
Гость
« Ответ #3 : Февраль 27, 2007, 21:37 »

widget->setParent(0) перед удалением.
Записан
QCasper
Гость
« Ответ #4 : Февраль 27, 2007, 22:13 »

Цитата: "Lion"
widget->setParent(0) перед удалением.


Че-то не помогло...
Записан
Вячеслав
Гость
« Ответ #5 : Февраль 28, 2007, 08:14 »

Код:
 dock->setWidget(0);
а так ?
Записан
Mikhail
Программист
*****
Online Online

Сообщений: 587


Просмотр профиля
« Ответ #6 : Февраль 28, 2007, 08:32 »

Попробуй
QDockWidget *dock = new QDockWidget;
QWidget *widget = new QWidget;
dock->setWidget(widget);
должно получиться.

В деструкторе, наверно приложения или mainwindow, проверь наличие ненулевого указателя на widget и в этом случае удали его с помощью delete.

добавлено спустя 52 секунды:

 Последнее предложение относится к случаю завершения приложения.
Записан
QCasper
Гость
« Ответ #7 : Февраль 28, 2007, 12:55 »

Цитата: "Mikhail"
Попробуй
QDockWidget *dock = new QDockWidget;
QWidget *widget = new QWidget;
dock->setWidget(widget);
должно получиться.

В деструкторе, наверно приложения или mainwindow, проверь наличие ненулевого указателя на widget и в этом случае удали его с помощью delete.

добавлено спустя 52 секунды:

 Последнее предложение относится к случаю завершения приложения.


QWidget *widget = new QWidget; - этот момент меня не устравивает, потому что этот виджет должен знать кто ему парент, потому как он своему паренту определенные настройки передает.

добавлено спустя 1 час:

 Вот код. На самом деле указатель на виджет который потом устанавливается на доквиджет, я получаю из плагина. Так вот если выгрузить плагин, то приложение падает по завершению, если не выгружать, а просто удалить виджет (m_Plugin->deactivate()), то не падает.

Код:
MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
m_Dw = new QDockWidget(this);
addDockWidget(Qt::RightDockWidgetArea, m_Dw);

m_Loader = new QPluginLoader("ddoverlay.dll", this);
if (m_Plugin = qobject_cast<IRenderingPlugin*>(m_Loader->instance()))
{
if (QWidget *wg = m_Plugin->activate(m_Dw, QSize(720,576)))
m_Dw->setWidget(wg);
}
QPushButton *btn = new QPushButton(this);
connect(btn, SIGNAL(clicked()), this, SLOT(deactivate()));

setCentralWidget(btn);
}

MainWindow::~MainWindow()
{
}
void MainWindow::deactivate() {
if (m_Plugin) {
m_Plugin->deactivate();
m_Dw->setWidget(0);
m_Loader->unload();
}
}


добавлено спустя 1 час 12 минут:

 Все прояснилось - полностью мой косяк. Там в этом плагине я паренту еще инсталил эвент фильтер. И забыл его удалить. Вот, и после того как плагин выгружался, адрес терялся, а при уничтожении доквиджета, последний пытался грохнуть этот эвент фильтер.
И вообще, как выяснилось, на будующее, если вы где-то мочите собственноручно чайлда, то он автоматически удаляется из списка чилдренов родителя. Цитата из асистанта:
Цитировать
You can also delete child objects yourself, and they will remove themselves from their parents.

Поэтому предложения типа "перед удалением setParent(0)" изначально не имели бы никакого эфекта.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.244 секунд. Запросов: 23.