Search code examples
python-3.xpyqt5qmessagebox

PyQt5 : clarifying connect() method in QMessageBox standardButtons


first, the code scope of my trouble:

from PyQt5 import QtWidgets, QtCore

# I found this function on the web:
def msgbtn(i):
    """
    This function works, and returns "Ok" or "Cancel" (string object).
    """
    print("Button pressed is:", i.text())
    return i.text()


# Create a basic message box
msg = QtWidgets.QMessageBox()
msg.setText("Try")
msg.setWindowTitle("My Title")
# Add the standard buttons "Ok" and "Cancel"
msg.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)

# Here, I tried to connect a function without argument, it works.
msg.buttonClicked.connect(msgbtn)

So at this point, I have "Ok" or "Cancel" returned in a string and it's good. However, I want to add an extra argument to this connected function (msgbtn). I did the command "type(i)" in the msnbtn and the i-object's class is QPushButton. The problem is that I did not find an attribute of the message box which belong to this class... I found the standardButton() which returns the "Ok" and "Cancel" standardButton class objects, and they do not have text attribute.

To go through this problem, I tried this:

def msgbtn(i, extra_arg):
    print(i)
    print(extra_arg)


msg.buttonClicked.connect(lambda: msgbtn(msg.result(), my_arg))

This method of the QMessageBox (Qt5 doc) returns 1024 if "OK" is pressed and 4194304 if "Cancel" is pressed.

I can deal with this to go further, but I ask you that someone knows which object of the messageBox is passed as argument when I call msg.buttonClicked.connect(msgbtn)?


Solution

  • The buttonClicked signal sends the button that was clicked. The documentation shows the parameter is of type QAbstractButton, which is an abstract base-class that is inherited by the QPushButton class.

    Your example code can be fixed like this:

    def msgbtn(button, arg):
        print(button.text())
        print(arg)
    
    msg.buttonClicked.connect(lambda button, arg=my_arg: msgbtn(button, arg))
    

    This caches the current value of my_arg as a default argument of the lambda.