I've created two dialogs in which Dialog1 is the parent of Dialog2. After navigating to dialog2 if i press close button in Dialog2, Dialog2 is closed but Dialog1 is displayed. Again i've to press the close button in Dialog1 to close the application (i know this happens coz. the close event propagates from child to parent).. Now i've two questions...
1) What should i do if i want to close the parent dialog as well??
2)If i want to reimplement the close in nchild dialog how can i achieve that???
Thanks in advance..

Recommended Answers

All 6 Replies

After navigating to dialog2 if i press close button in Dialog2, Dialog2 is closed but Dialog1 is displayed.

You should be able to close everything, otherwise you have to close dialog1 and close dialog2 within the same function.

## to close everything
    self.connect(self.pushButton, QtCore.SIGNAL('clicked()'), self.button_clicked)

    def button_clicked(self):
        print "close the window"
        self.close()

You'll have to post some example code for anything more specific.

## to close everything
    self.connect(self.pushButton, QtCore.SIGNAL('clicked()'), self.button_clicked)

    def button_clicked(self):
        print "close the window"
        self.close()

Thanks for replying.. If the close event is recommended through a button click it can be achieved in this manner.. But i want the dialog1 to close automatically when dialog 1 closes..
I've given a miniature reconstructed example here..

from PyQt4 import QtCore, QtGui

class Ui_Login(QtGui.QDialog):
    
    def __init__(self,parent=None):
        QtGui.QDialog.__init__(self,parent)
        self.setObjectName("Login")
        self.resize(550, 340)
        self.button=QtGui.QPushButton(self)
        self.button.setGeometry(250,170,70,25)
        self.button.setText("Press Me")
        
        self.show()
        QtCore.QObject.connect(self.button,QtCore.SIGNAL('clicked()'),self.showNextDlg)
        QtCore.QMetaObject.connectSlotsByName(self)
        
    def closeEvent(self,event):
        print('Inside Close Event of Parent Window')        

    def showNextDlg(self):
        self.newAccCreation=QtGui.QDialog(self)
        self.newAccCreation.setObjectName("Dialog")
        self.newAccCreation.resize(550, 340)
        self.newAccCreation.show()
        
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    loginScreen = Ui_Login()
    sys.exit(app.exec_())

How do i reimplement the catch event of the child dialog??
Can i make the parent window to close automatically when the child window is closed through the default close button(on the right-corner top)??

I would just add a self.close(), but that seems too easy so I guess that I still don't understand.

from PyQt4 import QtCore, QtGui
 
class Ui_Login(QtGui.QDialog):
 
    def __init__(self,parent=None):
        QtGui.QDialog.__init__(self,parent)
        self.setObjectName("Login")
        self.resize(550, 340)
        self.button=QtGui.QPushButton(self)
        self.button.setGeometry(250,170,70,25)
        self.button.setText("Press Me")
 
        self.show()
        QtCore.QObject.connect(self.button,QtCore.SIGNAL('clicked()'),self.showNextDlg)
        QtCore.QMetaObject.connectSlotsByName(self)
 
    def closeEvent(self,event):
        print('Inside Close Event of Parent Window')        
 
    def showNextDlg(self):
        ## ----------  added
        self.close()
        self.newAccCreation=QtGui.QDialog(self)
        self.newAccCreation.setObjectName("Dialog")
        self.newAccCreation.resize(550, 340)
        self.newAccCreation.show()
 
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    loginScreen = Ui_Login()
    sys.exit(app.exec_())

I would just add a self.close(), but that seems too easy so I guess that I still don't understand.

Yes still your'e not getting me.. I don't know whether i explained myself clearly or not.. well..
If i add self.close when the child dialog is displayed the window will not appear in the task bar since the parent was closed. If the end user(consider he's naive) navigates away from the window it'll be difficult to find it back.. Only way to find the window or dialog is thru. alt+tab or task mgr. -> Bring process to front or something, which is very annoying if it's a wizard based setup.. That's why i wanted to close the parent window when he presses the close button of it's child. One more thing i wanted to do here is i want to reimplement the close event of the child window so that once the setup wizard is completed i want the application to be minimized into the tray or something.. Am i made myself clear enough??

You would use hide() instead. If you want to keep track of separate dialogs, then you will have to store each one in a list, or somewhere, so you can access them individually. I have no time at the present to look at it further but running this example from the PyQt docs might help as I think it does what you are trying to do.

"""PyQt4 port of the dialogs/simplewizard example from Qt v4.x"""

import sys
from PyQt4 import QtCore, QtGui


class SimpleWizard(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)

        self.history = []
        self.numPages = 0
        
        self.cancelButton = QtGui.QPushButton(self.tr("Cancel"))
        self.backButton = QtGui.QPushButton(self.tr("< &Back"))
        self.nextButton = QtGui.QPushButton(self.tr("Next >"))
        self.finishButton = QtGui.QPushButton(self.tr("&Finish"))
    
        self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("reject()"))
        self.connect(self.backButton, QtCore.SIGNAL("clicked()"), self.backButtonClicked)
        self.connect(self.nextButton, QtCore.SIGNAL("clicked()"), self.nextButtonClicked)
        self.connect(self.finishButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("accept()"))
    
        buttonLayout = QtGui.QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.cancelButton)
        buttonLayout.addWidget(self.backButton)
        buttonLayout.addWidget(self.nextButton)
        buttonLayout.addWidget(self.finishButton)
    
        self.mainLayout = QtGui.QVBoxLayout()
        self.mainLayout.addLayout(buttonLayout)
        self.setLayout(self.mainLayout)

    def setButtonEnabled(self, enable):
        if len(self.history) == self.numPages:
            self.finishButton.setEnabled(enable)
        else:
            self.nextButton.setEnabled(enable)

    def setNumPages(self, n):
        self.numPages = n
        self.history.append(self.createPage(0))
        self.switchPage(0)

    def backButtonClicked(self):
        self.nextButton.setEnabled(True)
        self.finishButton.setEnabled(True)
    
        oldPage = self.history.pop()
        self.switchPage(oldPage)
        del oldPage

    def nextButtonClicked(self):
        self.nextButton.setEnabled(True)
        self.finishButton.setEnabled(len(self.history) == self.numPages - 1)
    
        oldPage = self.history[-1]
        self.history.append(self.createPage(len(self.history)))
        self.switchPage(oldPage)

    def switchPage(self, oldPage):
        if oldPage:
            oldPage.hide()
            self.mainLayout.removeWidget(oldPage)

        newPage = self.history[-1]
        self.mainLayout.insertWidget(0, newPage)
        newPage.show()
        newPage.setFocus()
    
        self.backButton.setEnabled(len(self.history) != 1)
        if len(self.history) == self.numPages:
            self.nextButton.setEnabled(False)
            self.finishButton.setDefault(True)
        else:
            self.nextButton.setDefault(True)
            self.finishButton.setEnabled(False)

        self.setWindowTitle(self.tr("Simple Wizard - Step %1 of %2")
                                    .arg(len(self.history)).arg(self.numPages))
                       

class ClassWizard(SimpleWizard):
    def __init__(self, parent=None):
        SimpleWizard.__init__(self, parent)

        self.setNumPages(3)

    def createPage(self, index):
        if index == 0:
            self.firstPage = FirstPage(self)
            return self.firstPage
        elif index == 1:
            self.secondPage = SecondPage(self)
            return self.secondPage
        elif index == 2:
            self.thirdPage = ThirdPage(self)
            return self.thirdPage

        return 0

    def accept(self):
        className = self.firstPage.classNameLineEdit.text().toAscii()
        baseClass = self.firstPage.baseClassLineEdit.text().toAscii()
        qobjectMacro = self.firstPage.qobjectMacroCheckBox.isChecked()
        qobjectCtor = self.firstPage.qobjectCtorRadioButton.isChecked()
        qwidgetCtor = self.firstPage.qwidgetCtorRadioButton.isChecked()
        defaultCtor = self.firstPage.defaultCtorRadioButton.isChecked()
        copyCtor = self.firstPage.copyCtorCheckBox.isChecked()
    
        comment = self.secondPage.commentCheckBox.isChecked()
        protect = self.secondPage.protectCheckBox.isChecked()
        macroName = self.secondPage.macroNameLineEdit.text().toAscii()
        includeBase = self.secondPage.includeBaseCheckBox.isChecked()
        baseInclude = self.secondPage.baseIncludeLineEdit.text().toAscii()
    
        outputDir = QtCore.QString(self.thirdPage.outputDirLineEdit.text())
        header = QtCore.QString(self.thirdPage.headerLineEdit.text())
        implementation = QtCore.QString(self.thirdPage.implementationLineEdit.text())
    
        block = QtCore.QByteArray()
    
        if comment:
            block += "/*\n"
            block += "    " + header.toAscii() + "\n"
            block += "*/\n"
            block += "\n"

        if protect:
            block += "#ifndef " + macroName + "\n"
            block += "#define " + macroName + "\n"
            block += "\n"

        if includeBase:
            block += "#include " + baseInclude + "\n"
            block += "\n"

        block += "class " + className
        if  not baseClass.isEmpty():
            block += " : public " + baseClass
        block += "\n"
        block += "{\n"
    
        # qmake ignore Q_OBJECT
    
        if qobjectMacro:
            block += "    Q_OBJECT\n"
            block += "\n"

        block += "public:\n"
    
        if qobjectCtor:
            block += "    " + className + "(QObject *parent);\n"
        elif qwidgetCtor:
            block += "    " + className + "(QWidget *parent);\n"
        elif defaultCtor:
            block += "    " + className + "();\n"
            if copyCtor:
                block += "    " + className + "(const " + className + " &other);\n"
                block += "\n"
                block += "    " + className + " &operator=" + "(const " + className + " &other);\n"

        block += "};\n"
    
        if protect:
            block += "\n"
            block += "#endif\n"

        headerFile = QtCore.QFile(outputDir + "/" + header)
        if  not headerFile.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text):
            QtGui.QMessageBox.warning(self, self.tr("Simple Wizard"),
                                      self.tr("Cannot write file %1:\n%2")
                                              .arg(headerFile.fileName())
                                              .arg(headerFile.errorString()))
            return

        headerFile.write(block)
    
        block.clear()
    
        if comment:
            block += "/*\n"
            block += "    " + implementation.toAscii() + "\n"
            block += "*/\n"
            block += "\n"

        block += "#include \"" + header.toAscii() + "\"\n"
        block += "\n"
    
        if qobjectCtor:
            block += className + "::" + className + "(QObject *parent)\n"
            block += "    : " + baseClass + "(parent)\n"
            block += "{\n"
            block += "}\n"
        elif qwidgetCtor:
            block += className + "::" + className + "(QWidget *parent)\n"
            block += "    : " + baseClass + "(parent)\n"
            block += "{\n"
            block += "}\n"
        elif defaultCtor:
            block += className + "::" + className + "()\n"
            block += "{\n"
            block += "    // missing code\n"
            block += "}\n"
    
            if copyCtor:
                block += "\n"
                block += className + "::" + className + "(const " + className + " &other)\n"
                block += "{\n"
                block += "    *this = other;\n"
                block += "}\n"
                block += "\n"
                block += className + " &" + className + "::operator=(const " + className + " &other)\n"
                block += "{\n"
                if  not baseClass.isEmpty():
                    block += "    " + baseClass + "::operator=(other);\n"
                block += "    // missing code\n"
                block += "    return *this;\n"
                block += "}\n"

        implementationFile = QtCore.QFile(outputDir + "/" + implementation)
        if  not implementationFile.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text):
            QtGui.QMessageBox.warning(self, self.tr("Simple Wizard"),
                                      self.tr("Cannot write file %1:\n%2")
                                              .arg(implementationFile.fileName())
                                              .arg(implementationFile.errorString()))
            return

        implementationFile.write(block)
    
        QtGui.QDialog.accept(self)
        

class FirstPage(QtGui.QWidget):
    def __init__(self, parent):
        QtGui.QWidget.__init__(self, parent)

        self.topLabel = QtGui.QLabel(self.tr("<center><b>Class information</b></center>"
                                             "<p>This wizard will generate a skeleton class "
                                             "definition and member function definitions."))
        self.topLabel.setWordWrap(False)
    
        self.classNameLabel = QtGui.QLabel(self.tr("Class &name:"))
        self.classNameLineEdit = QtGui.QLineEdit()
        self.classNameLabel.setBuddy(self.classNameLineEdit)
        self.setFocusProxy(self.classNameLineEdit)
    
        self.baseClassLabel = QtGui.QLabel(self.tr("&Base class:"))
        self.baseClassLineEdit = QtGui.QLineEdit()
        self.baseClassLabel.setBuddy(self.baseClassLineEdit)
    
        self.qobjectMacroCheckBox = QtGui.QCheckBox(self.tr("&Generate Q_OBJECT macro"))
    
        self.groupBox = QtGui.QGroupBox(self.tr("&Constructor"))
    
        self.qobjectCtorRadioButton = QtGui.QRadioButton(self.tr("&QObject-style constructor"))
        self.qwidgetCtorRadioButton = QtGui.QRadioButton(self.tr("Q&Widget-style constructor"))
        self.defaultCtorRadioButton = QtGui.QRadioButton(self.tr("&Default constructor"))
        self.copyCtorCheckBox = QtGui.QCheckBox(self.tr("&Also generate copy constructor "
                                                        "and assignment operator"))
    
        self.defaultCtorRadioButton.setChecked(True)
    
        self.connect(self.classNameLineEdit, QtCore.SIGNAL("textChanged(const QString &)"),
                self.classNameChanged)
        self.connect(self.defaultCtorRadioButton, QtCore.SIGNAL("toggled(bool)"),
                self.copyCtorCheckBox, QtCore.SLOT("setEnabled(bool)"))
    
        parent.setButtonEnabled(False)
    
        groupBoxLayout = QtGui.QVBoxLayout()
        groupBoxLayout.addWidget(self.qobjectCtorRadioButton)
        groupBoxLayout.addWidget(self.qwidgetCtorRadioButton)
        groupBoxLayout.addWidget(self.defaultCtorRadioButton)
        groupBoxLayout.addWidget(self.copyCtorCheckBox)
        self.groupBox.setLayout(groupBoxLayout)
    
        layout = QtGui.QGridLayout()
        layout.addWidget(self.topLabel, 0, 0, 1, 2)
        layout.setRowMinimumHeight(1, 10)
        layout.addWidget(self.classNameLabel, 2, 0)
        layout.addWidget(self.classNameLineEdit, 2, 1)
        layout.addWidget(self.baseClassLabel, 3, 0)
        layout.addWidget(self.baseClassLineEdit, 3, 1)
        layout.addWidget(self.qobjectMacroCheckBox, 4, 0, 1, 2)
        layout.addWidget(self.groupBox, 5, 0, 1, 2)
        layout.setRowStretch(6, 1)
        self.setLayout(layout)

    def classNameChanged(self):
        wizard = self.parent()
        wizard.setButtonEnabled(not self.classNameLineEdit.text().isEmpty())

        
class SecondPage(QtGui.QWidget):
    def __init__(self, parent):
        QtGui.QWidget.__init__(self, parent)

        self.topLabel = QtGui.QLabel(self.tr("<center><b>Code style options</b></center>"))
    
        self.commentCheckBox = QtGui.QCheckBox(self.tr("&Start generated files with a comment"))
        self.commentCheckBox.setChecked(True)
        self.setFocusProxy(self.commentCheckBox)
    
        self.protectCheckBox = QtGui.QCheckBox(self.tr("&Protect header file against "
                                                       "multiple inclusions"))
        self.protectCheckBox.setChecked(True)
    
        self.macroNameLabel = QtGui.QLabel(self.tr("&Macro name:"))
        self.macroNameLineEdit = QtGui.QLineEdit()
        self.macroNameLabel.setBuddy(self.macroNameLineEdit)
    
        self.includeBaseCheckBox = QtGui.QCheckBox(self.tr("&Include base class definition"))
        self.baseIncludeLabel = QtGui.QLabel(self.tr("Base class include:"))
        self.baseIncludeLineEdit = QtGui.QLineEdit()
        self.baseIncludeLabel.setBuddy(self.baseIncludeLineEdit)
    
        className = QtCore.QString(parent.firstPage.classNameLineEdit.text())
        self.macroNameLineEdit.setText(className.toUpper() + "_H")
    
        baseClass = QtCore.QString(parent.firstPage.baseClassLineEdit.text())
        if baseClass.isEmpty():
            self.includeBaseCheckBox.setEnabled(False)
            self.baseIncludeLabel.setEnabled(False)
            self.baseIncludeLineEdit.setEnabled(False)
        else:
            self.includeBaseCheckBox.setChecked(True)
            if QtCore.QRegExp("Q[A-Z].*").exactMatch(baseClass):
                self.baseIncludeLineEdit.setText("<" + baseClass + ">")
            else:
                self.baseIncludeLineEdit.setText("\"" + baseClass.toLower() + ".h\"")

        self.connect(self.protectCheckBox, QtCore.SIGNAL("toggled(bool)"),
                self.macroNameLabel, QtCore.SLOT("setEnabled(bool)"))
        self.connect(self.protectCheckBox, QtCore.SIGNAL("toggled(bool)"),
                self.macroNameLineEdit, QtCore.SLOT("setEnabled(bool)"))
        self.connect(self.includeBaseCheckBox, QtCore.SIGNAL("toggled(bool)"),
                self.baseIncludeLabel, QtCore.SLOT("setEnabled(bool)"))
        self.connect(self.includeBaseCheckBox, QtCore.SIGNAL("toggled(bool)"),
                self.baseIncludeLineEdit, QtCore.SLOT("setEnabled(bool)"))
    
        layout = QtGui.QGridLayout()
        layout.setColumnMinimumWidth(0, 20)
        layout.addWidget(self.topLabel, 0, 0, 1, 3)
        layout.setRowMinimumHeight(1, 10)
        layout.addWidget(self.commentCheckBox, 2, 0, 1, 3)
        layout.addWidget(self.protectCheckBox, 3, 0, 1, 3)
        layout.addWidget(self.macroNameLabel, 4, 1)
        layout.addWidget(self.macroNameLineEdit, 4, 2)
        layout.addWidget(self.includeBaseCheckBox, 5, 0, 1, 3)
        layout.addWidget(self.baseIncludeLabel, 6, 1)
        layout.addWidget(self.baseIncludeLineEdit, 6, 2)
        layout.setRowStretch(7, 1)
        self.setLayout(layout)

        
class ThirdPage(QtGui.QWidget):
    def __init__(self, parent):
        QtGui.QWidget.__init__(self, parent)
        
        self.topLabel = QtGui.QLabel(self.tr("<center><b>Output files</b></center>"))
    
        self.outputDirLabel = QtGui.QLabel(self.tr("&Output directory:"))
        self.outputDirLineEdit = QtGui.QLineEdit()
        self.outputDirLabel.setBuddy(self.outputDirLineEdit)
        self.setFocusProxy(self.outputDirLineEdit)
    
        self.headerLabel = QtGui.QLabel(self.tr("&Header file name:"))
        self.headerLineEdit = QtGui.QLineEdit()
        self.headerLabel.setBuddy(self.headerLineEdit)
    
        self.implementationLabel = QtGui.QLabel(self.tr("&Implementation file name:"))
        self.implementationLineEdit = QtGui.QLineEdit()
        self.implementationLabel.setBuddy(self.implementationLineEdit)
    
        className = QtCore.QString(parent.firstPage.classNameLineEdit.text())
        self.headerLineEdit.setText(className.toLower() + ".h")
        self.implementationLineEdit.setText(className.toLower() + ".cpp")
        self.outputDirLineEdit.setText(QtCore.QDir.convertSeparators(QtCore.QDir.homePath()))
    
        layout = QtGui.QGridLayout()
        layout.addWidget(self.topLabel, 0, 0, 1, 2)
        layout.setRowMinimumHeight(1, 10)
        layout.addWidget(self.outputDirLabel, 2, 0)
        layout.addWidget(self.outputDirLineEdit, 2, 1)
        layout.addWidget(self.headerLabel, 3, 0)
        layout.addWidget(self.headerLineEdit, 3, 1)
        layout.addWidget(self.implementationLabel, 4, 0)
        layout.addWidget(self.implementationLineEdit, 4, 1)
        layout.setRowStretch(5, 1)
        self.setLayout(layout)
        

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    wizard = ClassWizard()
    wizard.show()
    sys.exit(wizard.exec_())

In the constructor of the child widget assign the parent to some variable such as child.p since I don't think you can get at the parent otherwise. Then call child.p.close() within child.closeEvent().

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.