crossplatform.ru

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


  Ответ в Родитель виджета, не удаляющий дитёнка
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Алексей1153 Дата 12.11.2010, 22:48
  Litkevich Yuriy, ну так то да. Только там я почему-то решил идти сложным путём - вытаскивать список детей из родителя, а надо то было в своём списке всё и сделать было :D
Litkevich Yuriy Дата 12.11.2010, 22:45
 
Цитата(Алексей1153 @ 13.11.2010, 2:43) *
list[0]->setParent(0);
list[1]->setParent(0);
list[2]->setParent(0);

delete w;
собственно, я про это и говорил
Алексей1153 Дата 12.11.2010, 22:43
  финт ушами :) Ничего переопределять и не пришлось
    CWin* w=new CWin;
        
    list.push_back(new QWidget(w));
    list.push_back(new QWidget(w));
    list.push_back(new QWidget(w));
    
    list[0]->setParent(0);
    list[1]->setParent(0);
    list[2]->setParent(0);
    
    delete w;
    w=0;

    list[0]->show();
    list[1]->show();
    list[2]->show();

это работает
Алексей1153 Дата 12.11.2010, 21:53
  спасибо, конечно, но вот это
Цитата(kwisp @ 12.11.2010, 23:24) *
без qobject_cast не работает.

останавливает. Дело даже не в том, что я не пользуюсь кастом, а в том, что это всё костыль. Наверное, всё же лучше не трогать эту нелепую задумку авторов с удалением, а сделать иначе:

я же имею массив указателей на детей. Когда я хочу удалить окно, которое, как мне известно, может повлечь за собой удаление потомков, я должен пробежаться по массиву элементов и задать им родителя == 0.
kwisp Дата 12.11.2010, 21:24
 
Цитата(Алексей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 наследники
Алексей1153 Дата 12.11.2010, 21:06
  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;
}
panter_dsd Дата 12.11.2010, 20:52
  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.
kwisp Дата 12.11.2010, 20:37
  добавил в слот
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 вполне возможно что второй раз детки погибают от рук попаши.
Алексей1153 Дата 12.11.2010, 20:23
 
#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:22
 
Цитата(Алексей1153 @ 12.11.2010, 20:20) *
но факт. Проверил

я тебе не верю. код давай.
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 28.3.2024, 22:30