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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: когда вызывается деструктор класса?  (Прочитано 11578 раз)
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? Почему? Кто виноват, и что делать? Улыбающийся
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #1 : Сентябрь 24, 2012, 10:30 »

Qt:: WA_DeleteOnClose
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #2 : Сентябрь 24, 2012, 10:39 »

Закрытие QMainWindows != его уничтожению, eventLoop продолжает крутиться, обслуживая твоё окно-спутник. Может быть такой вот вызов главного окна поможет:
Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow *w = new MainWindow();
   w->setAttribute(Qt::WA_DeleteOnClose);
   w->show();
 
   return a.exec();
}
или вручную закрывать все созданые окна в void QWidget::closeEvent ( QCloseEvent * event ) [virtual protected]
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #3 : Сентябрь 24, 2012, 10:41 »

Qt:: WA_DeleteOnClose
Интересно, что произойдет с окном (объектом) с этим атрибутом, если оно создано не в куче, а на стеке?
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
PavelVX
Гость
« Ответ #4 : Сентябрь 24, 2012, 10:44 »

Ребята, без паники!
В конструкторе
wid1::wid1(...) {
...
setAttribute(Qt::WA_DeleteOnClose);
...}
Уже стоит, но не помогает.
Такой же атрибут стоит и на doc на который накладывается wid1.
В общем-то я и хотел, при закрытии виджета закрыть спутник.
Кстати, последовательность закрытия влияет на события.
1. Если закрывать wid1, то все нормально, выполнится деструктор, спутник закроется, дальше все как надо.
2. Если закрывать главное окно, то висим и ждем, пока не закроем спутник, тогда и деструктор вызовется. Кстати, тут непонятка есть: если я закрываю спутник, то он же должен удалиться? Значит указатель на него показывает хз куда. И вызывая wid1_1->close(); я обращаюсь непонятно куда. Но программа не рушится.
« Последнее редактирование: Сентябрь 24, 2012, 10:54 от PavelVX » Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #5 : Сентябрь 24, 2012, 10:55 »

Минимально компилируемый пример.
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Сентябрь 24, 2012, 11:17 »

Сделать указатель на спутник членом главного окна и в деструкторе удалять. Т.к. спутник может быть удален и самостоятельно здесь хорошо использовать QPointer
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Сентябрь 24, 2012, 11:22 »

повесь сигнал на wid1
Код
C++ (Qt)
connect( mainwindow, SIGNAL( destroyed() ), wid1, SLOT( close() ) );
« Последнее редактирование: Сентябрь 24, 2012, 11:52 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
PavelVX
Гость
« Ответ #8 : Сентябрь 24, 2012, 11:50 »

повесь сигнал на wid1
Код
C++ (Qt)
connect( mainwindow, SIGNAL( destroyed ), wid1, SLOT( close() ) );

Повесил, не помогает. Сделал так:
Код:
MainWindow::~MainWindow()
{
    qDebug() << "main";
}
Надпись появляется, когда я закрываю спутник. Все приложение ждет закрытия спутника Улыбающийся
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Сентябрь 24, 2012, 11:53 »

ну, а на MainWindow
Код
C++ (Qt)
setAttribute(Qt::WA_DeleteOnClose);
был выставлен?
Записан

Qt 5.11/4.8.7 (X11/Win)
PavelVX
Гость
« Ответ #10 : Сентябрь 24, 2012, 12:01 »

Нет.
Сейчас выставил.
Код:
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(100, 100, 800, 600);
    setAttribute(Qt::WA_DeleteOnClose);
    statusBar()->showMessage(tr("Ready"));

}

MainWindow::~MainWindow()
{
}

При закрытии программы происходит краш.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Сентябрь 24, 2012, 12:06 »

Нет.
Сейчас выставил.
Ну, а почему не читаешь советы Kurles Непонимающий

Цитировать
При закрытии программы происходит краш.
Опять же Kurles сразу тебе сказал о возможных проблемах.
Почему не читаем советы Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #12 : Сентябрь 24, 2012, 12:07 »

Нет.
Сейчас выставил.
Код:
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(100, 100, 800, 600);
    setAttribute(Qt::WA_DeleteOnClose);
    statusBar()->showMessage(tr("Ready"));

}

MainWindow::~MainWindow()
{
}

При закрытии программы происходит краш.
Qt:: WA_DeleteOnClose
Интересно, что произойдет с окном (объектом) с этим атрибутом, если оно создано не в куче, а на стеке?
Вот наверное ответ на мой вопрос ) В main(..) создвавй MainWindows не на стеке, а на куче, т.е. через оператор new.
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
PavelVX
Гость
« Ответ #13 : Сентябрь 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 )
{
    qDebug() << "close event";
    if (wid1)
    {
        qobject_cast< QDockWidget* >(wid1->parent())->close();
    }
}
« Последнее редактирование: Сентябрь 24, 2012, 12:28 от PavelVX » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #14 : Сентябрь 24, 2012, 12:22 »

За qobject_cast< QDockWidget* >(wid1->parent())->close() нужно руки выдирать.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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