crossplatform.ru

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

> При закрытии главного окна приложение не завершается
ilya
  опции профиля:
сообщение 18.4.2012, 10:11
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 18.4.2012
Пользователь №: 3330

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем привет.

По какой-то причине закрытие главного окна, унаследованного от QWidget, не приводит к завершению приложения. Причём не помогают завершить программу ни close(), ни destroy(), ни QApplication::exit(). close(), например, возвращает true, окно закрывается, но код внутри этого окна продолжает выполняться. Кто-нибудь сталкивался с такой проблемой?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 9)
wiz29
  опции профиля:
сообщение 18.4.2012, 10:30
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Можешь привести код функции main твоего приложения?
и заодно код виджета.

А также попробуй пересобрать (может поможет)

Сообщение отредактировал wiz29 - 18.4.2012, 10:32
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilya
  опции профиля:
сообщение 18.4.2012, 11:54
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 18.4.2012
Пользователь №: 3330

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(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
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


Попробуй как-нибудь так сделать:
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;
}


Сообщение отредактировал Snake174 - 18.4.2012, 12:08
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilya
  опции профиля:
сообщение 18.4.2012, 12:16
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 18.4.2012
Пользователь №: 3330

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Snake174 @ 18.4.2012, 13:04) *
Попробуй как-нибудь так сделать:

Этот код будет аварийно завершать приложение при неудачной попытке создать объект типа Recorder, потому что возникающее при этом исключение останется неперехваченным. Собственно, вопрос в том и состоит, как красиво завершить приложение при возникновении ошибки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Snake174
  опции профиля:
сообщение 18.4.2012, 12:25
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 89
Регистрация: 18.4.2011
Из: Миасс
Пользователь №: 2613

Спасибо сказали: 9 раз(а)




Репутация:   0  


А чем тебе такое не нравится? Сделай функцию Start() типа bool и в ней, если не удалось запустить, вывести ошибку.
bool Recorder::Start()
{
  // пытаемся запустить
  if (запустили)
  {
    ......

    return true;
  }

  // вывод ошибки
  .....

  return false;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilya
  опции профиля:
сообщение 18.4.2012, 12:45
Сообщение #7


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 18.4.2012
Пользователь №: 3330

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Snake174 @ 18.4.2012, 13:25) *
А чем тебе такое не нравится? Сделай функцию Start() типа bool и в ней, если не удалось запустить, вывести ошибку.


Дело в том, что класс Recorder - это мост между графическим интерфейсом и остальной, достаточно большой, частью программы, вся обработка ошибок в которой построена на исключениях. Хорошим тоном при разработке архитектуры программного продукта считается выработка единой стратегии обработки ошибок, поэтому применение исключений в классе Recorder не обсуждается. Вообще, мысль в корне правильная - при возникновении исключения в конструкторе деструктор класса не вызывается, что может привести к утечке ресурсов, и, возможно, как раз к тому, что программа перестанет правильно завершаться. Но все ресурсы в этом коде используются через смартпойнтеры, поэтому утечки ресурсов тут априори не может быть, и дело скорее всего не в этом.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 18.4.2012, 13:17
Сообщение #8


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Поставь для главного окна атрбут Qt::WA_DeleteOnClose;
По умолчанию окно не уничтожается при закрытии.
Либо вызывай вместо метода close в обработчике исключения qApp->quit()

Сообщение отредактировал wiz29 - 18.4.2012, 13:19
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilya
  опции профиля:
сообщение 18.4.2012, 13:35
Сообщение #9


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 18.4.2012
Пользователь №: 3330

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(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
Сообщение #10


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Видимо проблема не в этом месте, а других объектах - потоках возможно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 20:39