Search code examples
user-interfaceqtpyqtpyqt4multiple-forms

Multi-dialog program in PyQT will not close


For my project, I require multiple dialogs to be linked to each other. One button would go to one level, another button would go back two levels. To get a basic idea of what I'm looking for without showing all my code, here is a compilable example:

'''
Created on 2010-06-18

@author: dhatt
'''

import sys
from PyQt4 import QtGui, QtCore

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

        self.setGeometry(300, 300, 120, 150)
        self.setWindowTitle('LV3')

        quit = QtGui.QPushButton('Close', self)
        quit.setGeometry(10, 10, 60, 35)

        self.connect(quit, QtCore.SIGNAL('clicked()'),
            QtGui.qApp, QtCore.SLOT('quit()'))  # this will close entire program


class WindowLV2(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.Window3 = WindowLV3()

        self.setGeometry(300, 300, 120, 150)
        self.setWindowTitle('LV2')

        quit = QtGui.QPushButton('Close', self)
        quit.setGeometry(10, 10, 60, 35)

        next = QtGui.QPushButton('Lv3', self)
        next.setGeometry(10, 50, 60, 35)

        self.connect(quit, QtCore.SIGNAL('clicked()'),
            QtGui.qApp, QtCore.SLOT('reject()'))  # this doesn't work

        self.connect(next, QtCore.SIGNAL('clicked()'),
            self.nextWindow)

    def nextWindow(self):
        self.Window3.show()


class WindowLV1(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.Window2 = WindowLV2()

        self.setGeometry(300, 300, 120, 150)
        self.setWindowTitle('LV1')

        next = QtGui.QPushButton('Lv2', self)
        next.setGeometry(10, 50, 60, 35)

        quit = QtGui.QPushButton('Close', self)
        quit.setGeometry(10, 10, 60, 35)

        self.connect(next, QtCore.SIGNAL('clicked()'),
            self.nextWindow)

    def nextWindow(self):
        self.Window2.show()

        self.connect(quit, QtCore.SIGNAL('clicked()'),
            QtGui.qApp, QtCore.SLOT('reject()'))  # this doesn't work        


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

The problem is that I cannot close from a window and show the previous window. For instance, if I clicked on the 'CLOSE' button inside from a LV3 window, it will transfer control back to a LV2 window. I can call QtCore.SLOT('quit()')), but it will shut down the entire program, and I don't want that.

What am I doing wrong here?


Solution

  • there are two things that need to be addressed here.

    1. You can simply call QDialog.close in the connect method.

    2. In def nextWindow(self): you are trying to connect a local variable quit. So it won't work. You need to define quit as an instance variable (self.quit)

      self.connect(self.quit, QtCore.SIGNAL('clicked()'), self.close) # this should work

    Here is the modified code:

    import sys
    from PyQt4 import QtGui, QtCore
    
    class WindowLV3(QtGui.QDialog):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(300, 300, 120, 150)
            self.setWindowTitle('LV3')
    
            self.quit = QtGui.QPushButton('Close', self)
            self.quit.setGeometry(10, 10, 60, 35)
    
            self.connect(self.quit, QtCore.SIGNAL('clicked()'),
                self.close)  # this will close entire program
    
    
    class WindowLV2(QtGui.QDialog):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
            self.Window3 = WindowLV3()
    
            self.setGeometry(300, 300, 120, 150)
            self.setWindowTitle('LV2')
    
            self.quit = QtGui.QPushButton('Close', self)
            self.quit.setGeometry(10, 10, 60, 35)
    
            next = QtGui.QPushButton('Lv3', self)
            next.setGeometry(10, 50, 60, 35)
    
            self.connect(self.quit, QtCore.SIGNAL('clicked()'),
                self.close)  # this should work
    
            self.connect(next, QtCore.SIGNAL('clicked()'),
                self.nextWindow)
    
        def nextWindow(self):
            self.Window3.show()
    
    
    class WindowLV1(QtGui.QDialog):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
            self.Window2 = WindowLV2()
    
            self.setGeometry(300, 300, 120, 150)
            self.setWindowTitle('LV1')
    
            next = QtGui.QPushButton('Lv2', self)
            next.setGeometry(10, 50, 60, 35)
    
            self.quit = QtGui.QPushButton('Close', self)
            self.quit.setGeometry(10, 10, 60, 35)
    
            self.connect(next, QtCore.SIGNAL('clicked()'),
                self.nextWindow)
    
        def nextWindow(self):
            self.Window2.show()
    
            self.connect(self.quit, QtCore.SIGNAL('clicked()'),
                self.close)  # this should work        
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        Window1 = WindowLV1()
        Window1.show()
        sys.exit(app.exec_())