Russian Qt Forum

Qt => Общие вопросы => Тема начата: FluffyMan2000 от Декабрь 09, 2012, 16:45



Название: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 16:45
Доброго времени суток.

Делаю лабораторную работу на тему "многодокументный интерфейс". писать за меня не прошу. просто подскажите в чем ошибка.

Имеется QMainWindow с QMdiArea в качестве centralWodget. В QMdiArea создаются окна (объекты, наследники QTextEdit со своими слотами "сохранить", "сохранить как"). Реализовал вызов диалогового окна при закрытии документа и при закрытии главного окна что-то вроде "документ не сохранен. сохранить?".

Проблема в следующем:
1)если создаю несколько окон, и закрываю один за одним, то вылетает программа при закрытии последнего дочернего окна. То есть если создам одно окно и его закрою - вылетает с ошибкой в консоль "программа неожиданно завершилась"
2) если закрываю главное окно и в нем имеются дочерние - тоже вылетает с ошибкой той же самой.

Проект во вложении. Кому не лень, посмотрите пожалуйста. у меня уже мозг взрывается.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: V1KT0P от Декабрь 09, 2012, 17:31
Как минимум у тебя в функции:
Код
C++ (Qt)
void MainWindow::checkForActionsAvailable()
нету проверки:
Код
C++ (Qt)
ui->mdiArea->isActiveWindow()
Также при каждом касте qobject_cast надо проверять не возвращает ли он ноль.
Как по мне так у тебя проблемы с архитектурой из-за плохого понимания Qt.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 17:36
Также при каждом касте qobject_cast надо проверять не возвращает ли он ноль.
Как по мне так у тебя проблемы с архитектурой из-за плохого понимания Qt.

в чем непонимание? это (использование кастов) вообще в примерах Макса Шлее написано.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: V1KT0P от Декабрь 09, 2012, 17:40
в чем непонимание? это (использование кастов) вообще в примерах Макса Шлее написано.
qobject_cast это тебе не static_cast и может спокойно вернуть ноль и вот тут начнется веселье. Особенно если программа большая, а ошибка достаточно редкая.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 17:46
понял.

устроил проверку на ноль при сохранении в слотах delegateForSave и delegateForSaveAs - возвращает не ноль. но ошибка та же.

еще заметил, что если создать два документа и нажать в тулбаре сохранить, то диалог сохранения вылезет два раза.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: Mikhail от Декабрь 09, 2012, 18:02
Ты используешь QMdiArea и не прочитав описания класса подсовываешь ему не наследников QMdiSubWindow, а какую то "дрянь" наследников QTextEdit.

Из документации:
Subwindows in QMdiArea are instances of QMdiSubWindow. They are added to an MDI area with addSubWindow(). It is common to pass a QWidget, which is set as the internal widget, to this function, but it is also possible to pass a QMdiSubWindow directly.The class inherits QWidget, and you can use the same API as with a normal top-level window when programming. QMdiSubWindow also has behavior that is specific to MDI windows. See the QMdiSubWindow class description for more details.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: V1KT0P от Декабрь 09, 2012, 18:10
понял.
устроил проверку на ноль при сохранении в слотах delegateForSave и delegateForSaveAs - возвращает не ноль. но ошибка та же.
еще заметил, что если создать два документа и нажать в тулбаре сохранить, то диалог сохранения вылезет два раза.
Я же тебе уже указал на эту ошибку. Вот исправь для начала функцию "void MainWindow::checkForActionsAvailable()" на вот это, а затем уже выясняй что ты делаешь не так:
Код
C++ (Qt)
void MainWindow::checkForActionsAvailable()
{
   if( !ui->mdiArea->isActiveWindow() )
   {
       qDebug() << "Error: isActiveWindow() is false";
       return;
   }
   DocWindow *widget = qobject_cast<DocWindow*>( ui->mdiArea->activeSubWindow()->widget() );
   if( !widget )
   {
       qDebug() << "Error: activeSubWindow() is not DocWindow";
       return;
   }
   ui->actionUndo->setEnabled( widget->document()->isUndoAvailable() );
   ui->actionRedo->setEnabled( widget->document()->isRedoAvailable() );
   ui->actionPaste->setEnabled( widget->canPaste() );
}


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 18:50
понял.
устроил проверку на ноль при сохранении в слотах delegateForSave и delegateForSaveAs - возвращает не ноль. но ошибка та же.
еще заметил, что если создать два документа и нажать в тулбаре сохранить, то диалог сохранения вылезет два раза.
Я же тебе уже указал на эту ошибку. Вот исправь для начала функцию "void MainWindow::checkForActionsAvailable()" на вот это, а затем уже выясняй что ты делаешь не так:
Код
C++ (Qt)
void MainWindow::checkForActionsAvailable()
{
   if( !ui->mdiArea->isActiveWindow() )
   {
       qDebug() << "Error: isActiveWindow() is false";
       return;
   }
   DocWindow *widget = qobject_cast<DocWindow*>( ui->mdiArea->activeSubWindow()->widget() );
   if( !widget )
   {
       qDebug() << "Error: activeSubWindow() is not DocWindow";
       return;
   }
   ui->actionUndo->setEnabled( widget->document()->isUndoAvailable() );
   ui->actionRedo->setEnabled( widget->document()->isRedoAvailable() );
   ui->actionPaste->setEnabled( widget->canPaste() );
}

Объясните, зачем проверять mdiArea на isActiveWindow()? и еще, программа крашится и без вызова MainWindow::checkForActionsAvailable(). так что скорее всего не в ней дело.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: V1KT0P от Декабрь 09, 2012, 18:58
Объясните, зачем проверять mdiArea на isActiveWindow()? и еще, программа крашится и без вызова MainWindow::checkForActionsAvailable(). так что скорее всего не в ней дело.
По крайней мере у меня под Kubuntu в процессе работы твоей программы ui->mdiArea->activeSubWindow() возвращает ноль. И вот из-за этого программа падает.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 18:58
Ты используешь QMdiArea и не прочитав описания класса подсовываешь ему не наследников QMdiSubWindow, а какую то "дрянь" наследников QTextEdit.

Из документации:
Subwindows in QMdiArea are instances of QMdiSubWindow. They are added to an MDI area with addSubWindow(). It is common to pass a QWidget, which is set as the internal widget, to this function, but it is also possible to pass a QMdiSubWindow directly.The class inherits QWidget, and you can use the same API as with a normal top-level window when programming. QMdiSubWindow also has behavior that is specific to MDI windows. See the QMdiSubWindow class description for more details.

в примерах от Макса Шлее именно так и делается


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 19:00
Объясните, зачем проверять mdiArea на isActiveWindow()? и еще, программа крашится и без вызова MainWindow::checkForActionsAvailable(). так что скорее всего не в ней дело.
По крайней мере у меня под Kubuntu в процессе работы твоей программы ui->mdiArea->activeSubWindow() возвращает ноль. И вот из-за этого программа падает.

а с твоим кодом слота MainWindow::checkForActionsAvailable() не крашится при закрытии программы? и еще нюанс, у тебя Qt установлена еще нокиевская или диджитевская? потому что у меня уже был казус - программа собранная на нокиевской кьют некоректно работала на диждитевской кьют


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: V1KT0P от Декабрь 09, 2012, 19:18
а с твоим кодом слота MainWindow::checkForActionsAvailable() не крашится при закрытии программы? и еще нюанс, у тебя Qt установлена еще нокиевская или диджитевская? потому что у меня уже был казус - программа собранная на нокиевской кьют некоректно работала на диждитевской кьют
Да, не крашится. Сборка у меня из репозитория убунты 4.8.3.
Запусти под отладчиком и посмотри бэктрейс при падении, что может быть проще?


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 20:29
а с твоим кодом слота MainWindow::checkForActionsAvailable() не крашится при закрытии программы? и еще нюанс, у тебя Qt установлена еще нокиевская или диджитевская? потому что у меня уже был казус - программа собранная на нокиевской кьют некоректно работала на диждитевской кьют
Да, не крашится. Сборка у меня из репозитория убунты 4.8.3.
Запусти под отладчиком и посмотри бэктрейс при падении, что может быть проще?

давайте по-порядку: ты содаешь два документа, жмешь крестик в главном окне, вылазит дилаог. жмешь да. вылазят два диалога. жмешь дискард и у тебя программа не крашится? у меня крашится.

Qt 4.7.4 (32-х битная)


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 20:36
при запуске в режиме отладке в консоль вывалилось "Error: isActiveWindow() is false" и крашится все равно. спасибо за направление. буду дальше думать


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 21:06
Решил таким образом:

Код:
void MainWindow::checkForActionsAvailable()
{
    if (ui->mdiArea->subWindowList().count() != 0)
    {
        DocWindow *pDoc = qobject_cast<DocWindow*>(ui->mdiArea->activeSubWindow()->widget());

        if (pDoc != 0)
        {
            ui->actionUndo->setEnabled(pDoc->document()->isUndoAvailable());
            ui->actionRedo->setEnabled(pDoc->document()->isRedoAvailable());
            ui->actionPaste->setEnabled(pDoc->canPaste());
        }
    }
}

проблема была в том, что я приводил к DocWindow несуществующий объект, так как он закрывался почему-то (до сих пор не понял почему он уничтожался раньше времени)


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: V1KT0P от Декабрь 09, 2012, 22:14
проблема была в том, что я приводил к DocWindow несуществующий объект, так как он закрывался почему-то (до сих пор не понял почему он уничтожался раньше времени)
Вот про это я и говорил. Непонимание того как работает Qt приводит к неправильной архитектуре.
Советую для начала прочитать документацию( можно взять русский перевод ). Там много интересного написано и сразу приходит понимание как правильно надо использовать эту библиотеку.


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: FluffyMan2000 от Декабрь 09, 2012, 23:05
проблема была в том, что я приводил к DocWindow несуществующий объект, так как он закрывался почему-то (до сих пор не понял почему он уничтожался раньше времени)
Вот про это я и говорил. Непонимание того как работает Qt приводит к неправильной архитектуре.
Советую для начала прочитать документацию( можно взять русский перевод ). Там много интересного написано и сразу приходит понимание как правильно надо использовать эту библиотеку.

но проверка mdiArea->isActiveWindow() никак не спасало ситуацию у меня на WinXP Qt4.7.4

решение - это собственно:
1) проверка количества дочерних окон (т.е. есть ли что приводить к DocWindow)
2) проверка успешности приведения к DocWindow

вопрос к тебе, а остальные вещи в целом без ошибок написаны? я имею в виду не функциональность, а придерживание к философии Qt?


Название: Re: Qt: Вылетает программа при закрытии главного окна
Отправлено: Igors от Декабрь 10, 2012, 02:15
а остальные вещи в целом без ошибок написаны? я имею в виду не функциональность, а придерживание к философии Qt?
Написано вполне нормально, но код слишком мал и задача слишком проста чтобы говорить о какой-то философии - пока это просто "освоение инструментария"