Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Day от Март 04, 2013, 13:39



Название: Закрыть виджет
Отправлено: Day от Март 04, 2013, 13:39
Хочу, чтобы при закрытии виджета mw закрывался и виджет tx
[cpp]  QWidget *mw = new QWidget();
  .....
  QTextEdit *tx = new QTextEdit();
  QObject::connect (mw, SIGNAL(destroyed(QObject *)), tx, SLOT(close()));
  QObject::connect (mw, SIGNAL(destroyed(QObject *)), tx, SLOT(deleteLater())); [/cpp]
Но почему-то этого не происходит...


Название: Re: Закрыть виджет
Отправлено: alexis031182 от Март 04, 2013, 13:42
Код
C++ (Qt)
QTextEdit *tx = new QTextEdit(mw);


Название: Re: Закрыть виджет
Отправлено: Day от Март 04, 2013, 13:50
Код
C++ (Qt)
QTextEdit *tx = new QTextEdit(mw);
Но тогда tx будет внутри mw, а мне этого совершенно не хочется. Дело в том, что mw - небольшой "управляющий" виджет, что-то вроде стартера. А tx хочется сделать побольше, там результаты просматриваются.
Похожая штука была у меня в случае, когда mw происходил от QDialog. тогда лечит [cpp]
   QObject::connect (mw, SIGNAL(finished(int)), tx, SLOT(close()));[/cpp]


Название: Re: Закрыть виджет
Отправлено: alexis031182 от Март 04, 2013, 13:58
Ну тогда надо унаследоваться от QWidget и переопределить событие "closeEvent()". Естественно, что новоявленный класс должен будет иметь указатель на tx;


Название: Re: Закрыть виджет
Отправлено: Day от Март 04, 2013, 14:14
Ну тогда надо унаследоваться от QWidget и переопределить событие "closeEvent()". Естественно, что новоявленный класс должен будет иметь указатель на tx;
Понятно. Дело немного усложняется тем, что может быть несколько экземпляров tx. Значит надо будет создавать не просто указатель на tx, а список указателей типа QList, следить за закрытиями этих экземпляров....
Если более простого решения не найдется, придется наследовать mw от диалога, что в общем-то логично...


Название: Re: Закрыть виджет
Отправлено: alexis031182 от Март 04, 2013, 14:21
Можно QWidget унаследовать и в переопределённой closeEvent() отправлять свой сигнал о закрытии. Получится как с QDialog.


Название: Re: Закрыть виджет
Отправлено: Day от Март 04, 2013, 14:26
Спасибо! Похоже, это оптимальный вариант.


Название: Re: Закрыть виджет
Отправлено: Hellraiser от Март 04, 2013, 14:27
Не надо наследоваться. Поставь после создания виджета это:
Код:
mw->setAttribute(Qt::WA_DeleteOnClose, true);
соединять с deleteLater необязательно. И не забудь для QApplication указать setQuitOnLastWindowClosed(true)


Название: Re: Закрыть виджет
Отправлено: Day от Март 04, 2013, 19:24
И вам спасибо! Теперь надо выбрать из всех оптимальных вариантов самый оптимальный. ;)
Странно, что для такой в общем-то несложной штуки, требуется привлечение не самых очевидных способов.
Но я - не в обиде. Вот еще я узнал пару кустов и лиан в джунглях Qt :)


Название: Re: Закрыть виджет
Отправлено: Day от Март 04, 2013, 19:29
Цитировать
соединять с deleteLater необязательно.
Это уж я так, для полноты картинки. Первоначальный вариант был с close()


Название: Re: Закрыть виджет
Отправлено: Hellraiser от Март 04, 2013, 19:49
Странно, что для такой в общем-то несложной штуки, требуется привлечение не самых очевидных способов.
При закрытии виджета происходит его скрытие, а удалять (если не выставлен тот самый атрибут, который не выставлен по умолчанию) надо явно через delete. Поэтому в твоем коде сигнал destroyed не высылался и, соответственно, не вызывался слот закрытия другого окна. По этой же причине надо устанавливать setQuitOnLastWindowClosed(true), в противном случае приложение будет висеть невидимым.
По архитектуре приложения - может стоит попробовать QMdiArea (http://qt-project.org/doc/qt-4.8/qmdiarea.html#details)?


Название: Re: Закрыть виджет
Отправлено: Day от Март 04, 2013, 20:04
Еще раз спасибо за подробные объяснения.
Цитировать
По архитектуре приложения - может стоит попробовать QMdiArea?
Это я с удовольствием использую в другом проекте, там тоже куча заморочек, буду разбираться потихонечку... Но в данном случае оно того не стоит.
Тут конечно, хотелось бы понять механизмы... А они не всегда очевидны. Документация тут много не дает. Она дает перечень методов, но их взаимодействие остается в тайне. Вот такие разборки нас немного приближают к пониманию. Как говаривала одна моя знакомая: "Все приходит с опытом. Но опыт приходит поздно."


Название: Re: Закрыть виджет
Отправлено: Day от Март 05, 2013, 11:49
Hellraiser, Все получилось, хотя и не сразу. Дело в том, что после app->exec() у меня еще стояли всякие манипуляции (снятие и запись настроек), которые приводили к ошибке. Перекинул все это хозяйство в деструктор - все заработало