Hello! Tell me what to use to close windows in Qt? I use both functions at once to completely close the self.close () and self.destroy () window. Why I do this: 1) I wrote an application in which a dialog box is invoked, and when I click on the button, a table of 1,000,000 elements is built. So if you use just close (), then when you call this dialog box again, the table remains full! (That is, the old filled table is saved) This leaves the second item 2) Using only close (), the memory is not released. A table of 1,000,000 items remains in memory.

When using self.close () and self.destroy () at the same time, there are no such problems, so now I close the whole window in this way. Dedicate ignoramus please, am I doing the right thing?

  • And just destroy () does not close the window? - dlarchikov
  • Closes. But if you close the main window, the program remains running. That is, if you do not close (), and exit the program with an ordinary cross (Top right), the program remains to hang in the display. - Alexander Rublev
  • close closes, only the widget (form class), what happens next and how the program structure is implemented in you can only explain why the memory is not cleared. - Vyacheslav Savchenko
  • Thanks to everyone who responded! I am surprised how much you have) - Alexander Rublev

3 answers 3

QDialog does not implement its close method, so we are looking at the base one:

bool QWidget :: close () [slot]

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

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

If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted. No matter what the widget is visible or not.

The QApplication::lastWindowClosed() signal with the Qt::WA_QuitOnClose attribute set is closed. For transient windows such as splash screens, tool windows, and popup menus.

That is, when you call close a window instance can be destroyed if the Qt::WA_DeleteOnClose flag is Qt::WA_DeleteOnClose .

But you can never use either close or destroy , but only creating an instance on the stack, instead of a class field, as the author of the question seems to do.

I usually create a small class with the getResult function for modal dialogs:

 class MyTableDialog(QtGui.QDialog, ): __ui = None def __init__(self, parent): super(MyTableDialog, self).__init__(parent) ui = self.__ui = Ui_MyTableDialog() ui.setupUi(self) self.__my_setup_ui() def GetResult(self, *args, **kwds): self.__set_args_to_ui(*args, **kwds) if self.exec_() != self.Accepted: return return self.__get_res_from_ui() def __my_setup_ui(self): "Здесь дополнительно инициализируем интерфейс и связываем сигналы" def __set_args_to_ui(self, *args, **kwds): "Здесь устанавливаем данные в элементы интерфейса" def __get_res_from_ui(self): "Здесь вытаскиваем введённые в интерфейсе данные" # Пример использования class MyMainWindow(...): def GetUserTable(self, *args, **kwds): res = MyTableDialog(self).GetResult(*args, **kwds) if res is None: logging.info('Пользователь отказался от ввода') else: self.__parse_user_table_input(res) 

    We read the documentation for QWidget :

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

    As you can see, it says nothing about freeing the memory occupied by the QWidget object.

    I can not say how exactly the memory manager in python works, I will give c ++ code:

     void foo() { QWidget w; w.show(); .... w.close(); } void bar() { QWidget* pw = new QWidget(); w->show(); .... w->close(); } 

    Explanations:

    Function foo() :

    • creates an object of class QWidget ,
    • shows the window
    • doing something else ...
    • closes the window
    • the object w destroyed when it goes out of scope, the memory allocated for it is freed.

    bar() function:

    • creates an object of class QWidget in dynamic memory ,
    • shows the window
    • doing something else ...
    • closes the window
    • *pw object is not destroyed, and the memory occupied by it is not released, because the programmer does not intentionally call the operator delete .

      Excerpts from Qt Assistant: Original:

      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 a hidden event. If it ignores the event, nothing happens. QWidget :: closeEvent () accepts the close event.

      If the widget has the Qt :: WA_DeleteOnClose flag, the widget is also deleted. No matter what the widget is visible or not.

      The QApplication :: lastWindowClosed () signal with the Qt :: WA_QuitOnClose attribute set is closed. For transient windows such as splash screens, tool windows, and popup menus.

      Transfer:

      Closes this widget. Returns true if this widget has been closed; otherwise false .

      First sent to QCloseEvent . The widget is hidden if this event is resolved. If not, nothing happens. By default, inheritance from QWidget::closeEvent() allows the closing event.

      If the widget has a Qt :: WA_DeleteOnClose flag (Note from me, set via setAttribute (), for example, this-> setAttribute (Qt :: WA_DeleteOnClose)), it will also be deleted. The closing event is not delivered to the widget regardless of its visibility.

      The QApplication::lastWindowClosed() signal will be produced when the last visible main window (that is, the window without parent), with the Qt::WA_QuitOnClose attribute Qt::WA_QuitOnClose , has been closed. By default, this attribute is set for all widgets, except for transitional (temporary windows) such as particles on the screen, window tools and pop-up menus.

      Original:

      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 for all the child widgets, passing destroySubWindows for the destroyWindow parameter. Destroy subwidgets selectively first.

      This function is usually called from the QWidget destructor.

      Transfer:

      Frees up the system resources window. Invokes the window widget's constructor if the destroyWindow parameter is true . destroy() calls itself recursively for all child widgets by passing destroySubWindows for the destroyWindow parameter. In order to have more flexible management, you need to destroy the "sub-widgets" before.

      This function is usually called in a QWidget destructor.

      I apologize in advance for a free translation, I tried to translate the most correctly.

      • one
        Read the author's question more carefully, he has a dialogue. Dialogue has other documentation;) - ixSci
      • one
        @ixSci, isn't QDialog inherited from QWidget?) - Vyacheslav Savchenko
      • Inherited, but you have QWindow documentation, not QWidget - ixSci
      • one
        Most likely ixSci is right. I gave an example that close does not free memory! I tried to read the documentation, but my English is bad. - Alexander Rublev
      • @ixSci Changed the translation, made it from the QWidget documentation. - Vyacheslav Savchenko