Не вызывается функция closeEvent() в Qt

253
07 декабря 2021, 15:10

Довольно простая ситуация - мне нужно просто вызвать диалоговое окно при любой попытке закрыть приложение пользователем. В документации написано, что для этого необходимо переопределить функцию closeEvent(QCloseEvent *event); И я так и сделал.

Файл .h:

virtual void closeEvent(QCloseEvent *event) override;

Файл .cpp:

void BaseMode::closeEvent(QCloseEvent *event)
{
    qDebug() << "BaseMode::closeEvent ";
    // Вызов модального окна с вопросом, действительно ли пользователь хочет 
    // закрыть приложение
}

Однако при попытке закрыть приложение оно закрывается как обычно. Даже в консоль ничего не выводится, т.е. как будто эта функция и не переопределена вовсе, хотя она даже помечена как override и компилятор никаких ошибок или предупреждений не выдает. Класс BaseMode наследуется от QWidget и является базовым, абстрактным(не знаю, имеет ли это значение) для двух других классов. Понимаю, что проблема где-то в моём классе, косвенно или явно дающая такое поведение, однако, в чем именно проблема, понять никак не могу. Класс BaseMode просто создает весь интерфейс одного лишь основного виджета, на котором уже все остальное (кнопки, лэйблы, меню, и пр.).

При создании нового проекта с одним только виджетом все работает отлично. И я никак не могу понять, что может быть такого в коде, чтобы в одном проекте функция closeEvent(QCloseEvent* event) работала нормально, а в другом нет.

Поскольку я не знаю, где именно может быть проблема, прикреплю сразу ссылку на весь код: https://github.com/PunchGott/Scanner

Answer 1

У вас в коде есть класс BaseMode пронаследованный от QWidget. Данный класс уже является окном и способен отображать интерфейс. В тоже время в самом классе BaseMode вы создаете еще один виджет

m_mainWidget = new QWidget;

который используется как главное окно интерфейса.

Соответственно у вас получается 2 виджета:

1) собственно сам объект класса BaseMode
2) созданный внутри класса BaseMode объект класса QWidget

Поскольку для объекта класса BaseMode не вызывается метод show(), то вы его даже не видите (хотя по факту он есть), соответственно для него не вызывается ивент BaseMode::closeEvent(). Данный ивент будет вызываться для объекта m_mainWidget.

Вам необходимо избавиться от виджета m_mainWidget и работать непосредственно с вашим классом BaseMode.

Теперь что происходит с классами-наследниками:

Создание виджета тут:

QPointer<ReceivingMode> receiving = new ReceivingMode();

Тут создается экземпляр класса ReceivingMode, который вызывает конструктор BaseMode, который опять же создает и отображает обычный QWidget

m_mainWidget = new QWidget
...
m_mainWidget->show();

Соответственно все ивенты опять идут мимо ReceivingMode

Правильно создавать и отображать именно тот виджет, который вам надо, вызывая для него show

т.е.

QPointer<ReceivingMode> receiving = new ReceivingMode();
receiving->show();

или же разместить вызов show() в конструкторе

P.S. надеюсь понятно, если что спрашивайте)

READ ALSO
Запуск потока из абстрактного базового класса [дубликат]

Запуск потока из абстрактного базового класса [дубликат]

Нужно что бы конструктор абстрактного базового класса запускал в отдельном потоке чисто виртуальный метод, определённый дочерним классомЧто-то...

75
Ошибка линковки проекта c++

Ошибка линковки проекта c++

Писал программу для перевода чисел из DEC в HEX и наоборот разными функциями на Windows с помощью MVS, теперь пришла пора перенести программу на линукс,...

101
Отображает непонятные символы c++

Отображает непонятные символы c++

Пытаюсь сделать поиск участников из существующего файла, но отображает изначально непонятные цифры, в следствии чего как я подозреваю не дает...

76
С++ bass dll кириллица

С++ bass dll кириллица

Делаю свой плеер на C++ OpenGL Bass dll

80