Перейти к содержимому

Как закрыть окно qt

  • автор:

Как правильно закрыть окно?

У меня есть два окна, первое окно это окно политика конфидициальности. Второе окно открывается при соглашение на первое окно. Мне нужно что бы первое окно закрывалось сразу после открытия второго. Я пробовал через QApplication::quake и через имяпервогокласса::close().
Но возникает вторая проблема, второе окно не успевает открыться.
Я и в начало кода передвигал close и в конец и в середину, Ничего не помогло.
Каким образом БЕЗОПАСНО ЗАКРЫТЬ окно и успев открыть второе окошко.

  • Вопрос задан более трёх лет назад
  • 228 просмотров

Комментировать
Решения вопроса 2

Zifix

Яков Е @Zifix Куратор тега Qt

Почитайте любую книгу по Qt. Сэкономите кучу времени и найдёте ответы ещё на тысячу подобных вопросов.

Ответ написан более трёх лет назад
Комментировать
Нравится 3 Комментировать
Vitaly @vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)

#include #include int main(int argc, char *argv[]) < QApplication a(argc, argv); QMainWindow mainWindow; auto res = QMessageBox::question(&mainWindow, QMainWindow::tr("Just in case"), QMainWindow::tr("Are you sure?")); if (res == QMessageBox::Yes) < mainWindow.show(); return a.exec(); >else < return -1; >>

Смысл в том, что у вас первое окно — это модальный диалог (наследник QDialog, допустим). У него есть метод exec обычно, который возвращает результат (например согласился пользователь или нет). На основании результата и решайте, что делать дальше: показать окно или выйти из программы.

Как закрыть окно qt

На этом шаге мы рассмотрим реализацию этой операции .

В предыдущих шагах для закрытия окна мы использовали слот quit() и метод exit([returnCode=0]) объекта приложения. Однако эти методы не только закрывают текущее окно, но и завершают выполнение всего приложения. Чтобы закрыть только текущее окно, следует воспользоваться методом close() класса QWidget . Метод возвращает значение True , если окно успешно закрыто, и False — в противном случае. Закрыть сразу все окна приложения позволяет слот closeAllWindows() класса QApplication .

Если для окна атрибут WA_DeleteOnClose из класса QtCore.Qt установлен в значение True , то после закрытия окна объект окна будет автоматически удален, в противном случае окно просто скрывается. Значение атрибута можно изменить с помощью метода setAttribute() :

window.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)

После вызова метода close() или нажатия кнопки Закрыть в заголовке окна генерируется событие QEvent.Close . Если внутри класса определить метод с предопределенным названием closeEvent() , то это событие можно перехватить и обработать. В качестве параметра метод принимает объект класса QCloseEvent , который содержит методы accept() (позволяет закрыть окно) и ignore() (запрещает закрытие окна). Вызывая эти методы, можно контролировать процесс закрытия окна.

В качестве примера закроем окно по нажатию кнопки.

# -*- coding: utf-8 -*- from PyQt5 import QtCore, QtWidgets import sys app = QtWidgets.QApplication(sys.argv) window = QtWidgets.QWidget(flags=QtCore.Qt.Dialog) window.setWindowTitle("Закрытие окна из программы") window.resize(300, 70) button = QtWidgets.QPushButton("Закрыть окно", window) button.setFixedSize(150, 30) button.move(75, 20) button.clicked.connect(window.close) window.show() sys.exit(app.exec_())

Архив с файлом можно взять здесь.

Внешний вид приложения изображен на рисунке 1.

Рис.1. Внешний вид приложения

Примечание . Закрыв последнее окно приложения, мы тем самым автоматически завершим и само приложение. Не забывайте об этом.

Со следующего шага мы начнем рассматривать обработку сигналов и событий .

Как правильно закрыть окно Qt?

Есть многооконное приложение. Виджеты иногда меняют родителей и переходят из одного окна в другое. Возникает необходимость закрывать окна с остатками виджетов. Например, было два окна, в каждом по два QLabel . Из одного окна в другое перешел QLabel . Окно с оставшимся в нем одним QLabel больше не нужно и его можно полностью удалить со всеми виджетами в нем. Как теперь правильно удалить это окно, чтобы не было утечек памяти и других неприятных вещей? Или память освобождается автоматически?

Отслеживать
28.8k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков
задан 30 авг 2016 в 15:02
835 9 9 серебряных знаков 24 24 бронзовых знака

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Для каждого окна установите атрибут:

setAttribute(Qt::WA_DeleteOnClose); 

Этот атрибут делает следующее:

Makes Qt delete this widget when the widget has accepted the close event (see QWidget::closeEvent()).

Другими словами, когда окно получает QCloseEvent , оно самоуничтожается

Отслеживать
ответ дан 30 авг 2016 в 15:46
yrHeTateJlb yrHeTateJlb
8,052 15 15 серебряных знаков 35 35 бронзовых знаков
Для окна — вы имеете в виду для самого главного виджета в окне, у которого родитель — nullptr ?
30 авг 2016 в 17:06
@LNK, да, за остальные виджеты отвечают их родители
30 авг 2016 в 17:10

И память освободится, всё удалится, если я вызову close(); ? Просто сейчас попробовал закрыть окно, а потом обратится к его потомкам(вызвать метод show() и resize() ), которые должны были быть удалены(чтобы проверить удалились ли потомки). На экран ничего не выводится, но процесс остается запущен, хотя ни одного видимого окна нет. Отсюда возникли сомнения.

31 авг 2016 в 12:08

@LNK, когда уничтожается родитель, то он уничтожает всех потомков. Виджет верхнего уровня(окно) родителя не имеет, но благодаря атрибуту Qt::WA_DeleteOnClose оно самоуничтожится при закрытии. Если сомневаетесь, можете взять этот класс, написать в конце конструктора какого-нибудь окна new Watcher(this); и убедится, что все работает

31 авг 2016 в 12:38

@LNK, если перефразировать ваш вопрос, то получится «Что будет, если обратится к удаленному объекту?». Ответ — Undefined Behavior. Программа может нормально продолжить работать, может вылететь с ошибкой, может заполнить всю имеющуюся память нулями, может отформатировать жесткий диск. Короче, при обращении к удаленным объектам произойти может все что угодно, и это будет в рамках стандарта.

31 авг 2016 в 16:38

Виджет-родитель при уничтожении автоматически удалит своих потомков.

When QObjects are created on the heap (i.e., created with new), a tree can be constructed from them in any order, and later, the objects in the tree can be destroyed in any order. When any QObject in the tree is deleted, if the object has a parent, the destructor automatically removes the object from its parent. If the object has children, the destructor automatically deletes each child. No QObject is deleted twice, regardless of the order of destruction.

Другими словами если у вас что-то отображается в окне, то достаточно удалить виджет окна, об остальном позаботится система объектных иерархий Qt.

Как закрыть окно qt

Можно ли в qt как-то инициировать немедленное закрытие окна?

Наткнулся на такую вещь: вызов слота close() как метода класса не приводит к немедленному закытию окна (с вызовом closeEvent и далее деструктора окна). Окно закрывается, но где-то после (вероятно, закрытие ставится в какую-то внутреннюю qt-шную очередь). В результате, после вызова wnd->close() окно остается неуничтоженным, деструктор невызванным, а мне нужно дальше уничтожать различные объекты, которые можно уничтожать только после закрытия целой группы окон и вызова их деструкторов.

Re: close(), как сделать немедленное закрытие окна

От: _niko_
Дата: 28.01.14 14:10
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Можно ли в qt как-то инициировать немедленное закрытие окна?

А>Наткнулся на такую вещь: вызов слота close() как метода класса не приводит к немедленному закытию окна (с вызовом closeEvent и далее деструктора окна). Окно закрывается, но где-то после (вероятно, закрытие ставится в какую-то внутреннюю qt-шную очередь). В результате, после вызова wnd->close() окно остается неуничтоженным, деструктор невызванным, а мне нужно дальше уничтожать различные объекты, которые можно уничтожать только после закрытия целой группы окон и вызова их деструкторов.

Метод QWidget::close по умолчанию не предполагает разрушение объекта, ибо после закрытия можно захотеть ещё пообщаться с ним.

Для разрушения при закрытии используй:

QWidget::setAttribute(Qt::WA_DeleteOnClose, true);

Отмечу, установка подобного флага также доступна и в конструкторе, но данное решение считается устаревшим:

QWidget::QWidget(parent, Qt::WDestructiveClose); // Obsolete

Re[2]: close(), как сделать немедленное закрытие окна

От: _niko_
Дата: 28.01.14 17:08
Оценка: 1 (1)

С учетом вышесказанного (я про атрибут Qt::WA_DeleteOnClose) стоит уточнить что при выходе из метода QWidget::close объект удален не будет, он всего лишь будет отмечен как закрытый!
В очереди сообщений потока будет лежать сообщение адресованное данному виджету при дальнейшей обработки которого виджет как раз таки и удалиться.
Если необходимо дождаться его удаления тут же — это можно решить через локальную прокрутку очереди сообщений (QEventLoop), но так лучше не делать, а придумать другое решение изначально-сложившейся проблемы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *