Search code examples
pythonpyqtpyqt4qt-signalsqmessagebox

Connecting in PyQt4 QMessageBox fails to call the slot method


I was trying to analyse the sample code cited here: PyQt - QMessageBox Here's the snippet:

from PyQt4.QtGui import *
from PyQt4.QtCore import *


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        w = QWidget()
        b = QPushButton(self)
        b.setText("Show message!")

        b.clicked.connect(self.showdialog)
        w.setWindowTitle("PyQt Dialog demo")

    def showdialog(self):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Question)


        # self.connect(msg, SIGNAL('clicked()'), self.msgbtn)
        msg.buttonClicked.connect(self.msgbtn)

        msg.exec_()

    def msgbtn(self, i):
        print("Button pressed is:", i.text())



if __name__ == '__main__':
    app = QApplication([])
    w = Window()
    w.show()
    app.exec_()

There are two ways of connecting signals to slots in PyQt. For buttons, it's:

QtCore.QObject.connect(button, QtCore.SIGNAL(“clicked()”), slot_function)

or

widget.clicked.connect(slot_function)

Using it the second way works fine: the msgbtn slot method is called as intended. However, if I try to change it to the more usual, 'PyQt-onic' way of connecting (i.e. the first one - I commented it out in the snippet), the slot method is never called. Could anyone please help me out with this?


Solution

  • the signal you pass to SIGNAL is incorrect, the QMessageBox does not have the clicked signal but the signal is buttonClicked (QAbstractButton *) so the correct thing is:

    self.connect(msg, SIGNAL("buttonClicked(QAbstractButton *)"), self.msgbtn)
    

    On the other hand that is not the PyQt-onic style, but the old style which is not recommended to use, but we recommend using the new style.

    Old style:

    self.connect(msg, SIGNAL("buttonClicked(QAbstractButton *)"), self.msgbtn)
    

    New style:

    msg.buttonClicked.connect(self.msgbtn)
    

    For more detail read the docs.