Why does qApp. quit () require two calls from QDialog?

There is a code containing the main window and the dialog box. The dialog box starts immediately after the main one, because you need to pass the coordinates of the main one to it.

In the dialog box there is a button, when clicked, qApp.quit() is executed, however, for some reason, to exit, you need to click on the button 2 times. A double call to qApp.quit() doesn't do anything either

How do I make it so that the exit occurs only with one click? What is it about what's going on?

Code:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QDialog
 
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(610, 371)
        MainWindow.setWindowTitle("MainWindow")

class Ui_Dialog(QDialog):
    def __init__(self, x, y, parent=None):
        QDialog.__init__(self, parent)
        self.setGeometry(QtCore.QRect(x + 20, y + 50, 400, 213))
        self.pushButton = QtWidgets.QPushButton(self)
        self.pushButton.setGeometry(QtCore.QRect(20, 20, 361, 171))
        self.setWindowTitle("Dialog")
        self.pushButton.setText("ВЫЙТИ")
 
        self.pushButton.clicked.connect(self.onClick)
 
    def onClick(self):
        app.quit()
 
 
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()

dlg = Ui_Dialog(MainWindow.x(), MainWindow.y())
dlg.exec()

sys.exit(app.exec_())
Author: S. Nick, 2021-02-05

1 answers

Use signals to notify you of any changes or actions.

from PyQt5 import QtCore, QtGui, QtWidgets

 
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(610, 371)
        MainWindow.setWindowTitle("MainWindow")


class Ui_Dialog(QtWidgets.QDialog):
    myClicked = QtCore.pyqtSignal()                                   # <---
        
    def __init__(self, x, y, parent=None):
        super(Ui_Dialog, self).__init__(parent)
        
        self.setGeometry(QtCore.QRect(x + 20, y + 50, 400, 213))
        self.pushButton = QtWidgets.QPushButton(self)
        self.pushButton.setGeometry(QtCore.QRect(20, 20, 361, 171))
        self.setWindowTitle("Dialog")
        self.pushButton.setText("ВЫЙТИ")

        # при нажатии pushButton, хотим, закрыть MainWindow
        self.pushButton.clicked.connect(self.myClicked)                # <---
        
        # при нажатии pushButton, хотим, выйти из диалогового окна
        self.pushButton.clicked.connect(self.accept)                   # <---


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.show()

        dlg = Ui_Dialog(self.x(), self.y())
        dlg.myClicked.connect(self.onClick)                            # <---
        dlg.exec() 
        print('Диалог закрыт')

    def onClick(self):
        print('!!! onClick')
        # Закроем MainWindow, через мгновение, чтобы первым закрылся Ui_Dialog
        QtCore.QTimer.singleShot(0, self.close)                        # <--- !!!     


if __name__ == "__main__": 
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter a description of the image here

 2
Author: S. Nick, 2021-02-05 16:27:52