crossplatform.ru

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

3 страниц V  < 1 2 3 >  
Ответить в данную темуНачать новую тему
> Родитель виджета, не удаляющий дитёнка
Litkevich Yuriy
  опции профиля:
сообщение 12.11.2010, 19:55
Сообщение #11


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

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

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




Репутация:   94  


Цитата(Алексей1153 @ 12.11.2010, 23:06) *
void QWidget::destroy ( bool destroyWindow = true, bool destroySubWindows = true ) [protected]
не смущает?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 12.11.2010, 20:11
Сообщение #12


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

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


Цитата(Litkevich Yuriy @ 12.11.2010, 21:55) *
не смущает?

ни грамма. Защищённые функции можно вызывать из потомков

Но!

в деструкторе вызывать УЖЕ поздно, а сигналы
destroyed()),this,SL
destroyed(QObject*))

почему-то не происходят. Вот такая петрушка

Сообщение отредактировал Алексей1153 - 12.11.2010, 20:12
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 12.11.2010, 20:19
Сообщение #13


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


Цитата(Litkevich Yuriy @ 12.11.2010, 19:55) *
не смущает?

как раз и не должно.
Унаследовался от QWidget и вперёд. Со спецификатором доступа public при наследовании все public и protected методы QWidget должны стать public и protected что ли методами наследника.

Цитата(Алексей1153 @ 12.11.2010, 20:11) *
в деструкторе вызывать УЖЕ поздно
Цитата(Алексей1153 @ 12.11.2010, 19:06) *
This function is usually called from the QWidget destructor.

странно.

Цитата(Алексей1153 @ 12.11.2010, 20:11) *
почему-то не происходят.

это вообще странно. может все таки ты где то ошибся. код давай.
и по-моему даже если их поймаешь то будет поздно - т.к. деструкторы вызываются в обратном порядке вызова конструкторов. получается если сигнал вызывается перед деструктором QObject то вся виджетная часть уже удалена.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 12.11.2010, 20:20
Сообщение #14


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

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


Цитата(kwisp @ 12.11.2010, 22:15) *
странно.

но факт. Проверил

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 12.11.2010, 20:22
Сообщение #15


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


Цитата(Алексей1153 @ 12.11.2010, 20:20) *
но факт. Проверил

я тебе не верю. код давай.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 12.11.2010, 20:23
Сообщение #16


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

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


#pragma once

#include <QWidget>

class CWin : public QWidget
{
    Q_OBJECT
public:
    explicit CWin(QWidget *parent=0);
    
public slots:
    void preventChildrenKilling();
    void preventChildrenKilling(QObject *);
    
};



#include "CWin.h"

CWin::CWin(QWidget *parent) :QWidget(parent)
{
    connect(this,SIGNAL(destroyed()),this,SLOT(preventChildrenKilling()));
    connect(this,SIGNAL(destroyed(QObject*)),this,SLOT(preventChildrenKilling(QObject*)));
}

void CWin::preventChildrenKilling()
{
    destroy(true,false);
}
void CWin::preventChildrenKilling(QObject*)
{
    destroy(true,false);
}


    CWin* w=new CWin;
    
    std::vector<QWidget*> list;
    
    list.push_back(new QWidget(w));
    list.push_back(new QWidget(w));
    list.push_back(new QWidget(w));

    delete w;

    list[0]->show(); //тут нарушение сегментации (дитё уже убито)
    list[1]->show();
    list[2]->show();


что не так ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 12.11.2010, 20:37
Сообщение #17


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


добавил в слот
void CWin::preventChildrenKilling(QObject*)

std::cout << __PRETTY_FUNCTION__ << "\n";

при работе получил вывод
Цитата
./test
void CWin::preventChildrenKilling(QObject*)
Ошибка сегментирования


так что на сигнал destoyed() зря грешишь он вызывается и даже слот срабатывает

можно попробовать через deleteLater()
посмотреть в багрекере троллей баг на destroy твоей версии Qt

---------
Цитата(Алексей1153 @ 12.11.2010, 20:11) *
в деструкторе вызывать УЖЕ поздно,

хотя ты знаешь все поддается логике.
деструкторы вызываются в обратном порядке. ты к примеру используешь destroy в своем деструкторе .сначала вызывается в твоем destroy(true,false) а затемм - destroy(true,true) в деструкторе QWidget вполне возможно что второй раз детки погибают от рук попаши.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
panter_dsd
  опции профиля:
сообщение 12.11.2010, 20:52
Сообщение #18


Жаждущий знаний
***

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

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




Репутация:   3  


void QObject::destroyed ( QObject * obj = 0 ) [signal]
This signal is emitted immediately before the object obj is destroyed, and can not be blocked.
All the objects's children are destroyed immediately after this signal is emitted.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 12.11.2010, 21:06
Сообщение #19


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

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


kwisp, только сейчас обратил внимание, что в консоли вывод
Цитата
Object::connect: Attempt to bind non-signal CWin::destroyed()
Object::connect: Attempt to bind non-signal CWin::destroyed(QObject*)


определение в <qobject.h>
Цитата
Q_SIGNALS:
void destroyed(QObject * = 0);

- хм


Цитата(kwisp @ 12.11.2010, 22:37) *
посмотреть в багрекере троллей баг на destroy твоей версии Qt

это как делается ? и где



попробовал вызывать deleteLater() вместо delete. Потом, попозже, по мышиному событию вызвал show для детей - тоже вылет.

Похоже, остаётся только так
Цитата(kwisp @ 12.11.2010, 20:47) *
что то типа:
void killWidgetWithoutChildren(QWidget* wgt)
{
foreach(wgt->children(), QObject* obj) if(obj->isWidget()) obj->reparent(NULL);
delete wgt;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 12.11.2010, 21:24
Сообщение #20


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


Цитата(Алексей1153 @ 12.11.2010, 21:06) *
Похоже, остаётся только так

так точно
только правда что то типа. я скоренько накатал рабочий вариант. завернешь в функцию сам.
int main(int a, char** B)
{
  QApplication app(a,B);
  CWin* w = new CWin;
  QWidget* wgt = new QWidget(w);
  foreach(QObject* obj, w->children()) {
    if(obj->isWidgetType()) {
      std::cout << __func__ << '\n';
      qobject_cast<QWidget*>(obj)->setParent(NULL);
    }
  }
  delete w;
  wgt->show();
  return app.exec();
}

без qobject_cast не работает. что очень интересно.
а всё дело в setParent - их две в QObject и QWidget :)
как делать со всеми кнопками и лейблами. не знаю на сколько корректно будет приводить их к QWidget* думаю прокатит т.к. они все его прямые public наследники
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 29.3.2024, 1:09