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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Падение приложения при удалении окна  (Прочитано 8000 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« : Сентябрь 28, 2016, 11:21 »

Наткнулся на интересный пример. Есть qml форма, на ней кнопка. По нажатию на кнопку нужно закрыть, после чего удалить окно, вроде все просто, но приложение при этом стабильно крашится. Я упускаю какие то моменты ?

main.cpp
Код:
#include <QApplication>

#include "windowmanager.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    WindowManager manager;
    manager.showWindow();

    return a.exec();
}

windowmanager.h
Код:
#ifndef WINDOWMANAGER_H
#define WINDOWMANAGER_H

#include <QObject>
#include <QDeclarativeView>

class WindowManager : public QObject
{
    Q_OBJECT
    public:
        explicit WindowManager(QObject *parent = 0);

        void showWindow();
        Q_INVOKABLE void closeWindow();

        QDeclarativeView *window();

    private:
        QDeclarativeView *m_window;

};

#endif // WINDOWMANAGER_H


windowmanager.cpp
Код:
#include "windowmanager.h"

#include <QDeclarativeContext>

WindowManager::WindowManager(QObject *parent) : QObject(parent), m_window(0)
{
}

void WindowManager::showWindow()
{
    window()->show();
}

void WindowManager::closeWindow()
{
    m_window->close();

    if (m_window != 0) {
        delete m_window;
        m_window = 0;
    }
}

QDeclarativeView *WindowManager::window()
{
    if (m_window == 0) {
        m_window = new QDeclarativeView(0);

        m_window->rootContext()->setContextProperty("manager",this);
        m_window->setSource(QUrl("qrc:/main.qml"));
    }

    return m_window;
}

main.qml
Код:
import QtQuick 1.1

Item {
    width: 500
    height: 500

    Rectangle {
        width: 200
        height: 200

        anchors.centerIn: parent

        color: "red"

        Text {
            anchors.centerIn: parent
            color: "white"

            text: "Click for crash"
        }

        MouseArea {
            anchors.fill: parent

            onClicked: {
                manager.closeWindow();
            }
        }
    }
}
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #1 : Сентябрь 28, 2016, 11:28 »

Можно попробовать не
Код
C++ (Qt)
delete m_window;
 
а
Код
C++ (Qt)
m_window->deleteLater();
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #2 : Сентябрь 28, 2016, 11:41 »

Пробовал. В этом случае приложение падает не у всех пользователей. Процентов 20ть пользователей все равно при этом ловит краши.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #3 : Сентябрь 28, 2016, 11:42 »

Да и еще очень важный момент. Краш возникает только если кликнуть по кнопке. Если я например повешу хот кей, на закрытие и удаление окна, на туже ф-цию, все будет хорошо.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Сентябрь 28, 2016, 12:29 »

Коли речь идёт о закрытии приложения, то может логичнее сделать так:
cpp:
Код
C++ (Qt)
m_window->rootContext()->setContextProperty("app",qApp);
qml:
Код
Javascript
onClicked: { app.quit(); }
Записан

Qt 5.11/4.8.7 (X11/Win)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #5 : Сентябрь 28, 2016, 12:47 »

К сожалению речь не о закрытии приложения. Данный пример просто иллюстрирует проблему. Есть приложение, в котором достаточно много qml окон, одно из них выполняет определенное действие после чего закрывается и удаляется, но я никак не могу понять, почему приложение падает после удаления окна.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Сентябрь 28, 2016, 13:03 »

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

Попробуй
Код
C++ (Qt)
void WindowManager::closeWindow()
{
   m_window->hide();
   m_window->deleteLater();
}
Записан

Qt 5.11/4.8.7 (X11/Win)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #7 : Сентябрь 28, 2016, 13:14 »

Согласен с тем что delete несколько жестко. Но как я уже писал выше, есть процентов 20 пользователей и только на mac os которые ловят краши и на deleteLater()

delete - просто помог локализовать проблему.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Сентябрь 28, 2016, 13:28 »

есть процентов 20 пользователей и только на mac os которые ловят краши и на deleteLater()
А ты уверен, что именно на нём? Что показывает backtrace в отладчике?
Записан

Qt 5.11/4.8.7 (X11/Win)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #9 : Сентябрь 28, 2016, 13:47 »

если используем deleteLater()

к сожалению backtrace не могу посмотреть, так как у самого эта проблема не воспроизводится. Как уже говорил выше, приложение падает у достаточно узкого контингента людей и только под macos. Отчет системы показывает вот что

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libQt5Core.5.dylib               0x000000010bea94b5 QCoreApplication::notifyInternal(QObject*, QEvent*) + 85
1   libQt5Gui.5.dylib                0x000000010fcb64b6 QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) + 1958
2   libQt5Gui.5.dylib                0x000000010fca4e5b QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 315
3   libQt5Gui.5.dylib                0x000000010fca3123 QWindowSystemInterface::flushWindowSystemEvents() + 579
4   libqcocoa.dylib                  0x0000000111e33882 QCocoaWindow::windowShouldClose() + 34
5   libqcocoa.dylib                  0x0000000111e3ee1b -[QNSWindowDelegate windowShouldClose:] + 27
6   com.apple.AppKit                 0x00007fff94534f44 __19-[NSWindow __close]_block_invoke + 134
7   com.apple.AppKit                 0x00007fff94534e79 -[NSWindow __close] + 251
8   com.apple.AppKit                 0x00007fff94534d55 -[NSWindow _close:] + 146
9   com.apple.AppKit                 0x00007fff944e8260 -[NSApplication sendAction:to:from:] + 327
10  com.apple.AppKit                 0x00007fff944e80de -[NSControl sendAction:to:] + 86
11  com.apple.AppKit                 0x00007fff94534c4d -[NSCell _sendActionFrom:] + 128
12  com.apple.AppKit                 0x00007fff9454e655 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2316
13  com.apple.AppKit                 0x00007fff9454da27 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 487
14  com.apple.AppKit                 0x00007fff9454d13d -[NSControl mouseDown:] + 706
15  com.apple.AppKit                 0x00007fff949e4831 -[_NSThemeWidget mouseDown:] + 304
16  com.apple.AppKit                 0x00007fff944cea58 -[NSWindow sendEvent:] + 11296
17  libqcocoa.dylib                  0x0000000111e2f0a7 -[QNSWindow superSendEvent:] + 39
18  libqcocoa.dylib                  0x0000000111e2eaf7 -[QNSWindowHelper handleWindowEvent:] + 423
19  com.apple.AppKit                 0x00007fff9446d5d4 -[NSApplication sendEvent:] + 2021
20  libqcocoa.dylib                  0x0000000111e455ce -[QNSApplication sendEvent:] + 78
21  com.apple.AppKit                 0x00007fff942bd9f9 -[NSApplication run] + 646
22  libqcocoa.dylib                  0x0000000111e41e64 QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 2420
23  libQt5Core.5.dylib               0x000000010bea6a0e QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 398
24  libQt5Core.5.dylib               0x000000010bea9a87 QCoreApplication::exec() + 359


Если мы не удаляем окно, не важно как delete или deletaLater() ошибки не возникает. Но если используем delete ошибка возникает у всех и сразу. Возникает вопрос, как правильно было удалять окно, через сигналы\слоты поведение тоже не предсказуемо.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #10 : Сентябрь 28, 2016, 13:56 »

Видимо проблема со событийной системе. То есть приложение добавляет некоторое событие в очередь, после delete убивается получатель. Но при этом попадает в notify где уже и происходит краш. Но почему, все же есть краши при deleteLater() не понятно, ведь он должен это учитывать. При этом, краши у небольшого круга людей.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #11 : Сентябрь 28, 2016, 14:02 »

Можно попробовать грязный хак:
Код
C++ (Qt)
QTimer::singleShot(1000, m_window, SLOT(deleteLater()));
или перед deleteLater() вызвать
Код
C++ (Qt)
m_window->disconnect();
« Последнее редактирование: Сентябрь 28, 2016, 14:03 от Hellraiser » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Сентябрь 28, 2016, 14:17 »

..через сигналы\слоты поведение тоже не предсказуемо.
Может все-таки стоит проверить сигнал с QueuedConnection соединенный со слотом-убийцей
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #13 : Сентябрь 29, 2016, 12:44 »

Код:
QTimer::singleShot(1000, m_window, SLOT(deleteLater()));

Не сработал

QueuedConnection проверил, тоже не прокатило. При этом вызов функции удаления через keyPress каким то хоткеем отрабатывает хорошо. При этом не важно, какой из методов использовать и delete работает и deleteLater и все эти извращения с таймером :-)
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #14 : Сентябрь 29, 2016, 13:02 »

При этом вызов функции удаления через keyPress каким то хоткеем отрабатывает хорошо.
А кем и как keyPress обрабатывается?
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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