pythonpython-3.xpyqtpyqt5

PyQt5 - pythonw.exe crash on handling clicked event


I'm new to PyQt5 and I've got an error (pythonw.exe not working anymore) with the following code:

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
from PyQt5.QtCore import QCoreApplication


class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):               
        
        qbtn = QPushButton('Quit', self)
        qbtn.clicked.connect(self.q)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(50, 50)       

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Quit button')    
        self.show()

    def q():
        print('test')
        sys.exit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    app.exec_()

First it works, but only until I push the "quit" button. Then the error message pops up. If I put the q() function outside the class (and change "self.q" into "q") it works fine. What's the problem?

Thanks in advance.


Solution

  • that's because when q() is inside the class it's expects a compulsory argument as the first parameter, this is usually called self and is passed for you implicitly by python when you're calling the method (q() not q(self)). just as you've done with the initUI method in your class, when you put it outside the class, it's just a normal function and not a method again (function in a class), so it's fine to define the function without self

    import sys
    from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
    from PyQt5.QtCore import QCoreApplication
    
    class Example(QWidget):
    
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):               
            qbtn = QPushButton('Quit', self)
            qbtn.clicked.connect(self.q)
            qbtn.resize(qbtn.sizeHint())
            qbtn.move(50, 50)       
    
            self.setGeometry(300, 300, 250, 150)
            self.setWindowTitle('Quit button')    
            self.show()
    
        def q(self):
            print('test')
            sys.exit()
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = Example()
        app.exec_()