Pyqt close all windows

Proper way to handle the close button in a main window PyQt, (Red “X”)

First off, I am a complete newbie to PyQt.

I have been trying to link a function to the Main Window’s close button (the red x in the corner of the window) but I haven’t been having any success. Right now, my code looks something like this:

In a seperate «main» file I have the folowing:

However, when I run via command prompt, I am not able to see the print statement when I hit the red x. I know I am new to Qt, but I have seen quite a few people ask this question, and none of the answers seemed to get beyond what is already written above.

Both of these solutions are similar to mine, but it still doesn’t work

Despite the answer, which may have worked for that user’s specific code, my fellow PyQt colleagues and I are still quite foggy on the reasoning ours is not working. Is there a defined button name for the «Red X box» built into PyQt? Can I connect it to another function the someway I would for other buttons?

3 Answers 3

You shouldn’t ever modify the class that was generated from your ui file. Instead you should subclass and modify the subclass.

From the looks of your code, you are actually creating two QMainWindow s and the closeEvent is being caught for the wrong one (presumably that one is hidden?). That is self.ui is a QMainWindow that is not being shown, and is not added to the UI of GUIForm . Instead you are using the Ui_MainWindow.setupUi() method explicitly yourself, to add the widgets to your own QMainWindow , ‘GUIForm`.

Instead, what you should to do is leave your Ui_MainWindow class as it was when it was generated from the ui file, and then modify your main python file to be:

This way you are extending the behaviour of the auto-generated UI file. This makes it easy to regenerate the python file from the .ui file without having to re-add code (this is precisely why you should never modify the auto-generated Python file)

Close a window in PyQt5 in Python

Hey folks, This tutorial will help you to close a window in PyQt5 in Python. This can be achieved by using a simple method of the QWidget class. We will use that method and learn how to achieve our goal in a few ways. So for this, we are going to use some libraries of Python namely: PyQt5 and sys.

How to close a window in PyQt5

To close a window in PyQt5 we use the .close() method on that window. We can simply achieve this by calling the .close() method whenever we want to close the window or by some following ways:

  1. Calling the .close() method whenever needed.
  2. Binding to a PushButton to trigger the .close() method.
  3. Creating a QAction and adding it to the window to trigger the .close() method.
Читайте также:  Не могу удалить библиотеку windows media player

Calling the .close() method whenever needed

Create your PyQt5 application and just call the .close() method whenever that window needs closing. For example:

The above program creates a simple PyQt5 application with a QLabel as its central widget and then finally, closes it. So the window will be created, the widget will be added but it won’t be displayed as it was closed as soon as it was created.

NOTE: The above-mentioned program is just a demonstration on how to use .close() method when needed to close a window. It’s not a full-flexed application. So nothing will be displayed as mentioned earlier.

Binding to a PushButton to trigger the .close() method

In this way of closing the window, we create a QPushButton() and then bind a function(to close the window) to it which is triggered when that button is clicked. For example:

The above program creates a simple PyQt5 application with a QPushButton() as its central widget and then binds a function to trigger on click. The function is a simple lambda function that calls the self.close() method.It’s bound to QPushButton() using the .clicked.connect() method.So when the button is clicked the window closes.

Creating a QAction and adding it to the window to trigger the .close() method

In this way of closing the window, we create a QAction() and then add that action to the window we want to close using the .addAction() method. For example:

pyqt5 — closing/terminating application

I’m working though the pyqt5 tutorial found here Zetcode, PyQt5

As an exercise for myself I’m trying to expand on an example so that I am presented with the same dialog message box regardless of method used to close the app:

  • clicking the ‘X’ button in the title bar (works as intended)
  • clicking the ‘Close’ button (produces attribute error)
  • pressing the ‘escape’ key (works but not sure how/why)

The dialog message box is implemented in the closeEvent method, full script provided at the end.

I’m having two issues:

1. When clicking ‘Close’ button, instead of just quitting, I want to call closeEvent method including message box dialog.

I have replaced a line of the example code for the ‘Close’ push button:

And instead am trying to call the closeEvent method which already implements the dialog I want:

However when i run the script and click the ‘Close’ button and select the resulting ‘Close’ option in the dialog i get the following:

Can anyone advise what I’m doing wrong and what needs to be done here?

2. When hitting the escape key somehow the message box dialog is presented and works just fine.

Ok, it’s great that it works, but I’d like to know how and why the message box functionality defined in CloseEvent method is called within the keyPressEvent method.

Full script follows:

Hope someone can take the time to enlighten me.

Читайте также:  Красивый терминал linux mint

PyQt5 opening and closing windows

I have two UI windows created with QT Designer. I have two separate python scripts for each UI. What I’m trying to do is the first script opens a window, creates a thread that looks for a certain condition, then when found, opens the second UI. Then the second UI creates a thread, and when done, opens the first UI.

This seems to work fine, here’s the partial code that is fired when the signal is called:

So that appears to work fine. I am still unsure of the proper way to kill the thread, the docs seem to state exit() or quit(). But. the new window from the other script (L79Fuel.py) is shown and the old window destroyed.

Then the new window does some things, and again when a signal is called, it triggers an similar function that I’d like to close that window, and reopen the first window.

And this just exits with a code 0. I stepped through it with a debugger, and what seems to be happening is it runs through start_first , does everything in the function, and then goes back to the first window’s sys.exit(app.exec_()) , does that line, and then loops back to the start_first function (the second window) and executes that code again, in a loop, over and over.

I’m stumped. I’ve read as much as I could find, but nothing seems to address this. I’m guessing there’s something I’m doing wrong with the threading (both windows have a thread going) and I’m not killing the threads correctly, or something along those lines.

Что использовать в Qt close() или destroy()?

Всем привет! Подскажите что использовать для закрытия окон в Qt? Я использую сразу обе функции для полного закрытия окна self.close() и self.destroy() Почему я так делаю: 1) Я написал приложение в котором вызывается диалоговое окно, и при нажатии на кнопку строиться таблица из 1,000,000 элементов. Так вот если использовать просто close(), то при повторном вызове этого диалогового окна таблица остается заполненной!(То есть сохраняется старая заполненная таблица) Из этого выходит второй пункт 2) При использовании только close(), память не освобождается. Таблица из 1,000,000 элементов остается в памяти.

При использовании self.close() и self.destroy() одновременно, таких проблем нет, поэтому я сейчас все окно закрываю таким способом. Посвятите неуча пожалуйста, правильно ли я делаю?

3 ответа 3

QDialog не реализует свой метод close , стало быть смотрим в базовом:

Closes this widget. Returns true if the widget was closed; otherwise returns false .

First it sends the widget a QCloseEvent . The widget is hidden if it accepts the close event. If it ignores the event, nothing happens. The default implementation of QWidget::closeEvent() accepts the close event.

If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted. A close events is delivered to the widget no matter if the widget is visible or not.

The QApplication::lastWindowClosed() signal is emitted when the last visible primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose attribute set is closed. By default this attribute is set for all widgets except transient windows such as splash screens, tool windows, and popup menus.

Читайте также:  Драйвер windows для планшета lenovo

Т. е. при вызове close экземпляр окна может быть уничтожен, если выставлен флаг Qt::WA_DeleteOnClose .

Но можно вовсе не использовать ни close , ни destroy , а только создание экземпляра на стеке, вместо поля класса, как похоже, делает автор вопроса.

Я, обычно для модальных диалогов создаю небольшой класс с функцией getResult :

Closes this widget. Returns true if the widget was closed; otherwise returns false.

Как можно заметить, здесь ничего не говорится об освобождении памяти, занимаемой объектом QWidget .

Не могу сказать, как точно работает менеджер памяти в python, приведу код на c++:

  • создаёт объект класса QWidget ,
  • показывает окно,
  • делает что-то ещё.
  • закрывает окно,
  • объект w уничтожается при выходе из области видимости, память отведённая для него освобождается.
  • создаёт объект класса QWidget в динамической памяти,
  • показывает окно,
  • делает что-то ещё.
  • закрывает окно,
  • объект *pw не уничтожается, а память им занимаемая не освобождается, т.к. программист намеренно не вызывает оператор delete .

Выдержки из Qt Assistant: Оригинал:

bool QWidget::close() Closes this widget. Returns true if the widget was closed; otherwise returns false.

First it sends the widget a QCloseEvent. The widget is hidden if it accepts the close event. If it ignores the event, nothing happens. The default implementation of QWidget::closeEvent() accepts the close event.

If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted. A close events is delivered to the widget no matter if the widget is visible or not.

The QApplication::lastWindowClosed() signal is emitted when the last visible primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose attribute set is closed. By default this attribute is set for all widgets except transient windows such as splash screens, tool windows, and popup menus.

Закрывает этот виджет. Возвращает true , если этот виджет был закрыт; иначе false .

Сначала посылается в QCloseEvent . Виджет скрывается если это событие разрешается. Если нет, тот ничего не происходит. По умолчанию наследование от QWidget::closeEvent() разрешает закрывающее событие.

Если виджет имеет Qt::WA_DeleteOnClose флаг(Примечание от меня, задавать через setAttribute(), например, this->setAttribute(Qt::WA_DeleteOnClose)), то он ещё и будет удалён. Событие закрытия не доставляется в виджет в не зависимости от его видимости.

Сигнал QApplication::lastWindowClosed() будет произведён, когда последнее видимое главное окно(т.е. окно без родителя), с установленным атрибутом Qt::WA_QuitOnClose , было закрыто. По умолчанию этот атрибут установлен для всех виджетов, кроме переходных(временных окон) таких, как частички на экране, оконные инструменты и всплывающие меню.

void QWidget::destroy(bool destroyWindow = true, bool destroySubWindows = true) Frees up window system resources. Destroys the widget window if destroyWindow is true.

destroy() calls itself recursively for all the child widgets, passing destroySubWindows for the destroyWindow parameter. To have more control over destruction of subwidgets, destroy subwidgets selectively first.

This function is usually called from the QWidget destructor.

Освобождает окно системных ресурсов. Вызывает конструктор виджета окна, если параметр destroyWindow равен true . destroy() вызывает себя рекурсивно для всех дочерних виджетов, проходя destroySubWindows для параметра destroyWindow . Для того, чтобы иметь более гибкое управление нужно разрушить «подвиджеты» раньше.

Эта функция обычно вызывается в QWidget деструкторе.

Заранее извиняюсь за вольный перевод, старался наиболее правильно перевести.

Оцените статью