Название: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 24, 2012, 10:23 Ситуация следующая: есть
class MainWindow : public QMainWindow. На него укладываются QDockWidget на которых мои виджеты(wid1, wid2, ...). В wid1, при определенном действии, создается wid1_1, widAdv = new wid1_1(); widAdv->show(); // this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); (это прописано в конструкторе wid1_1) Таким образом получаем рядом с основной программой, окно спутник, которое всегда сверху, где все действия взаимодействуют через сигналы и слоты. Но вот приходит время закрытия программы. Закрываем основное окно, спутник не закрывается. Вроде бы логично, поскольку спутник не имеет родителя. Но возникает вопрос: а как тогда закрывать спутник при закрытии программы? Попробовал вставить это в деструктор ~wid1{ wid1_1->close(); qDebug() << "destr"; } В итоге получаю странный результат: Если закрывать wid1, то деструктор вызывается сразу и все проходит как надо. Если же закрывать QMainWindow, то деструктор не вызывается, пока ВРУЧНУЮ не закроется wid1_1? Почему? Кто виноват, и что делать? :) Название: Re: когда вызывается деструктор класса? Отправлено: Пантер от Сентября 24, 2012, 10:30 Qt:: WA_DeleteOnClose
Название: Re: когда вызывается деструктор класса? Отправлено: Kurles от Сентября 24, 2012, 10:39 Закрытие QMainWindows != его уничтожению, eventLoop продолжает крутиться, обслуживая твоё окно-спутник. Может быть такой вот вызов главного окна поможет:
Код или вручную закрывать все созданые окна в void QWidget::closeEvent ( QCloseEvent * event ) [virtual protected] Название: Re: когда вызывается деструктор класса? Отправлено: Kurles от Сентября 24, 2012, 10:41 Qt:: WA_DeleteOnClose Интересно, что произойдет с окном (объектом) с этим атрибутом, если оно создано не в куче, а на стеке?Название: Re: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 24, 2012, 10:44 Ребята, без паники!
В конструкторе wid1::wid1(...) { ... setAttribute(Qt::WA_DeleteOnClose); ...} Уже стоит, но не помогает. Такой же атрибут стоит и на doc на который накладывается wid1. В общем-то я и хотел, при закрытии виджета закрыть спутник. Кстати, последовательность закрытия влияет на события. 1. Если закрывать wid1, то все нормально, выполнится деструктор, спутник закроется, дальше все как надо. 2. Если закрывать главное окно, то висим и ждем, пока не закроем спутник, тогда и деструктор вызовется. Кстати, тут непонятка есть: если я закрываю спутник, то он же должен удалиться? Значит указатель на него показывает хз куда. И вызывая wid1_1->close(); я обращаюсь непонятно куда. Но программа не рушится. Название: Re: когда вызывается деструктор класса? Отправлено: Kurles от Сентября 24, 2012, 10:55 Минимально компилируемый пример.
Название: Re: когда вызывается деструктор класса? Отправлено: Igors от Сентября 24, 2012, 11:17 Сделать указатель на спутник членом главного окна и в деструкторе удалять. Т.к. спутник может быть удален и самостоятельно здесь хорошо использовать QPointer
Название: Re: когда вызывается деструктор класса? Отправлено: GreatSnake от Сентября 24, 2012, 11:22 повесь сигнал на wid1
Код
Название: Re: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 24, 2012, 11:50 повесь сигнал на wid1
Код C++ (Qt) connect( mainwindow, SIGNAL( destroyed ), wid1, SLOT( close() ) ); Повесил, не помогает. Сделал так: Код: MainWindow::~MainWindow() Название: Re: когда вызывается деструктор класса? Отправлено: GreatSnake от Сентября 24, 2012, 11:53 ну, а на MainWindow
Код был выставлен? Название: Re: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 24, 2012, 12:01 Нет.
Сейчас выставил. Код: MainWindow::MainWindow(QWidget *parent) Название: Re: когда вызывается деструктор класса? Отправлено: GreatSnake от Сентября 24, 2012, 12:06 Нет. Ну, а почему не читаешь советы Kurles ???Сейчас выставил. Цитировать При закрытии программы происходит краш. Опять же Kurles сразу тебе сказал о возможных проблемах.Почему не читаем советы ??? Название: Re: когда вызывается деструктор класса? Отправлено: Kurles от Сентября 24, 2012, 12:07 Нет. Сейчас выставил. Код: MainWindow::MainWindow(QWidget *parent) Qt:: WA_DeleteOnClose Интересно, что произойдет с окном (объектом) с этим атрибутом, если оно создано не в куче, а на стеке?Название: Re: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 24, 2012, 12:19 СПАСИБО всем!!!
Отдельное спасибо: 1. Kurles за void QWidget::closeEvent ( QCloseEvent * event ) [virtual protected]! (тут я просмотрел, мой косяк) 2. Igors за QPointer (про это я не знал, использовал похожую самописную фигнюшку) 3. GreatSnake за попытку повторно обратить мое внимание на п1. В итоге все заработало. Сейчас нужные части на QPointer переведу и будет красивый и читабельный код. Еще раз спасибо! Код: void MainWindow::closeEvent ( QCloseEvent * event ) Название: Re: когда вызывается деструктор класса? Отправлено: Пантер от Сентября 24, 2012, 12:22 За qobject_cast< QDockWidget* >(wid1->parent())->close() нужно руки выдирать.
Название: Re: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 24, 2012, 12:25 Почему? Мне же нужно удалить виджет, на который я накладываю свой класс? Как правильнее?
Название: Re: когда вызывается деструктор класса? Отправлено: GreatSnake от Сентября 24, 2012, 12:26 2. GreatSnake за QPointer (про это я не знал, использовал похожую самописную фигнюшку) и за попытку повторно обратить мое внимание Про QPointer говорил Igors.И ещё раз повторюсь, самый безопасный и практичный способ здесь (http://www.prog.org.ru/index.php?topic=23113.msg163190#msg163190). Название: Re: когда вызывается деструктор класса? Отправлено: Странник от Сентября 24, 2012, 14:59 Почему? Мне же нужно удалить виджет, на который я накладываю свой класс? Как правильнее? ну хотя бы потому, что:- если у wid1 нет родителя - крэш. - если родитель wid1 не QDockWidget - крэш. - есть QWidget * QWidget::parentWidget () const - кастить нет никакого смысла, можно вызвать bool QWidget::close () [slot]. и сделать это, кстати говоря, через сигнал-слот, как вам предложил GreatSnake. Название: Re: когда вызывается деструктор класса? Отправлено: PavelVX от Сентября 25, 2012, 06:46 голосу более опытных товарищей внял, код переписал. Спасибо.
|