Версия для печати темы
Форум на CrossPlatform.RU _ Qt GUI _ При закрытии главного окна приложение не завершается
Автор: ilya 18.4.2012, 10:11
Всем привет.
По какой-то причине закрытие главного окна, унаследованного от QWidget, не приводит к завершению приложения. Причём не помогают завершить программу ни close(), ни destroy(), ни QApplication::exit(). close(), например, возвращает true, окно закрывается, но код внутри этого окна продолжает выполняться. Кто-нибудь сталкивался с такой проблемой?
Автор: wiz29 18.4.2012, 10:30
Можешь привести код функции main твоего приложения?
и заодно код виджета.
А также попробуй пересобрать (может поможет)
Автор: ilya 18.4.2012, 11:54
Цитата(wiz29 @ 18.4.2012, 11:30)
Можешь привести код функции main твоего приложения?
и заодно код виджета.
А также попробуй пересобрать (может поможет)
Код сначала не стал приводить, но сейчас проблема частично локализовалась
Происходит следующее:
1. метод Start() вызывает метод StartRecorder()
2. метод StartRecorder() пытается создать объект типа Recorder
3. объект при создании кидает исключение типа RecorderError
4. в обработчике исключения почему-то не вызывается деструктор окна
5. точка выполнения возвращается в функцию Start(), где на второй строке программа успешно сегфолтится
void MainForm::Start()
{
StartRecorder();
// Здесь, в итоге, пытаемся обратиться по непроинициализированному указателю
RecordInfo info = recorder->GetRecordInfo();
}
void MainForm::StartRecorder()
{
try {
recorder = new Recorder;
recorder->Start();
}
catch (RecorderError &err) {
QMessageBox::critical(this, tr("Ошибка"), err.GetErrorDescription());
// Здесь, теоретически, должен вызываться деструктор, но этого не происходит
close();
}
}
Пересобирать, конечно, пробовал, и в дебаге и в релизе, но безуспешно.
P.S. Код функции main() стандартный:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainForm w;
w.show();
return a.exec();
}
Автор: Snake174 18.4.2012, 12:04
Попробуй как-нибудь так сделать:
void MainForm::Start()
{
if (StartRecorder())
{
RecordInfo info = recorder->GetRecordInfo();
// делаем что-то с info
......
}
else
close();
}
bool MainForm::StartRecorder()
{
recorder = new Recorder;
if (recorder)
{
if (!recorder->Start())
{
RecorderError err;
QMessageBox::critical(this, tr("Ошибка"), err.GetErrorDescription());
delete recorder;
recorder = 0;
return false;
}
}
return true;
}
Автор: ilya 18.4.2012, 12:16
Цитата(Snake174 @ 18.4.2012, 13:04)
Попробуй как-нибудь так сделать:
Этот код будет аварийно завершать приложение при неудачной попытке создать объект типа Recorder, потому что возникающее при этом исключение останется неперехваченным. Собственно, вопрос в том и состоит, как красиво завершить приложение при возникновении ошибки.
Автор: Snake174 18.4.2012, 12:25
А чем тебе такое не нравится? Сделай функцию Start() типа bool и в ней, если не удалось запустить, вывести ошибку.
bool Recorder::Start()
{
// пытаемся запустить
if (запустили)
{
......
return true;
}
// вывод ошибки
.....
return false;
}
Автор: ilya 18.4.2012, 12:45
Цитата(Snake174 @ 18.4.2012, 13:25)
А чем тебе такое не нравится? Сделай функцию Start() типа bool и в ней, если не удалось запустить, вывести ошибку.
Дело в том, что класс Recorder - это мост между графическим интерфейсом и остальной, достаточно большой, частью программы, вся обработка ошибок в которой построена на исключениях. Хорошим тоном при разработке архитектуры программного продукта считается выработка единой стратегии обработки ошибок, поэтому применение исключений в классе Recorder не обсуждается. Вообще, мысль в корне правильная - при возникновении исключения в конструкторе деструктор класса не вызывается, что может привести к утечке ресурсов, и, возможно, как раз к тому, что программа перестанет правильно завершаться. Но все ресурсы в этом коде используются через смартпойнтеры, поэтому утечки ресурсов тут априори не может быть, и дело скорее всего не в этом.
Автор: wiz29 18.4.2012, 13:17
Поставь для главного окна атрбут Qt::WA_DeleteOnClose;
По умолчанию окно не уничтожается при закрытии.
Либо вызывай вместо метода close в обработчике исключения qApp->quit()
Автор: ilya 18.4.2012, 13:35
Цитата(wiz29 @ 18.4.2012, 14:17)
Поставь для главного окна атрбут Qt::WA_DeleteOnClose;
По умолчанию окно не уничтожается при закрытии.
Либо вызывай вместо метода close в обработчике исключения qApp->quit()
Попробовал вставить в main() строку
w.setAttribute(Qt::WA_DeleteOnClose);
- не помогает. Написал маленький тестовый пример, где по нажатию кнопки вызывается close() - завершается нормально и без установки этого флага.
А qApp->quit() - это ведь то же самое, что и qApp->exit(0), и тоже не работает.
Автор: wiz29 18.4.2012, 14:25
Видимо проблема не в этом месте, а других объектах - потоках возможно.
Автор: ilya 18.4.2012, 14:41
Да, может быть. Ещё поищу сам, спасибо.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)