What do the different QMessageBox.Roles mean?

I am investigating the behavior of a custom alert box to which I add different buttons using:

msgBox.addButton(<button text>, QtGui.QMessageBox.XRole)

      

If the various possible roles (i.e. X values) are listed in the documentation .

My question is, what is the status of these roles, and what are the rules for using them? I can't find anything explicit in the documentation, and when I use any role other than Destructive

, Accept

or Reject

when executed QMessageBox

, it looks like it doesn't return as expected, as in the following simple example:

# -*- coding: utf-8 -*-
import sys
from PySide import QtGui

class Form(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        #Make a few buttons
        warnButton=QtGui.QPushButton("Warn Me")
        self.readoutLabel=QtGui.QLabel("Waiting for inputs from dialog")
        layout = QtGui.QVBoxLayout() 
        layout.addWidget(warnButton)
        layout.addWidget(self.readoutLabel)
        self.setLayout(layout)
        warnButton.clicked.connect(self.warnSlot)

    def warnSlot(self):
        self.readoutLabel.setText("Waiting for inputs from dialog")
        msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Warning,  
                "QMessageBox(QMessageBox.Warning...)", "Will you heed this fancy custom warning?!",
                QtGui.QMessageBox.NoButton, self)
        msgBox.addButton("Accept", QtGui.QMessageBox.AcceptRole)
        msgBox.addButton("I reject you!", QtGui.QMessageBox.RejectRole)
        msgBox.addButton("Destroy!", QtGui.QMessageBox.DestructiveRole)  
        msgBox.addButton("Yes!", QtGui.QMessageBox.YesRole)
        reply=msgBox.exec_()  #seems to always be 0,1, or 2
        print "Actual reply: " , reply
        if reply == QtGui.QMessageBox.DestructiveRole:  
            self.readoutLabel.setText("Response to warning: Destroy")
        elif reply == QtGui.QMessageBox.RejectRole:
            self.readoutLabel.setText("Response to warning: Reject")
        elif reply == QtGui.QMessageBox.AcceptRole:  
            self.readoutLabel.setText("Response to warning: Accept")
        elif reply == QtGui.QMessageBox.YesRole:
            self.readoutLabel.setText("Response to warning: Yes")

if __name__ == '__main__':
    qtApp = QtGui.QApplication(sys.argv)
    ex = Form()
    ex.show()
    sys.exit(qtApp.exec_())

      

When you click the Yes button, unlike the other buttons, it doesn't seem to be registered by the caller. It looks like these roles are not inert, but have underlying mechanics and usage expectations that I am blind to.

+3


source to share


1 answer


The return value QMessageBox::exec

is meaningful only if you are using the standard buttons in the dialog. But you're technically using custom buttons, in which case it exec()

returns the index of the button (but you shouldn't rely on that fact either because it's not fixed in the documentation). The correct results for buttons other than the yes button are just coincidence. If you add an "accept" button after adding a "reject" button, you will also start getting incorrect results for those buttons.

You can use QMessageBox::buttonRole

and QMessageBox::currentButton

to get the actual role:

msgBox.exec_()
reply = msgBox.buttonRole(msgBox.clickedButton())

      

If you have multiple buttons with the same role, you can save each button object and compare QMessageBox::currentButton

against each button object:



yes_button = msgBox.addButton("Yes!", QtGui.QMessageBox.YesRole)
msgBox.exec_()
if msgBox.clickedButton() == yes_button:
  print("Response to warning: Yes")    

      

The purpose of button roles is to provide a consistent appearance of messages for message boxes. The positions of the buttons will differ depending on their roles and the current OS. For example, a "help" button will appear on the left or right depending on where it usually appears in the native dialog boxes of the current OS.

Note. exec()

will give correct results if you use standard buttons. Curiously, I haven't found a way to use them in PySide: QMessageBox::addButton(StandardButton)

not available in PySide; QMessageBox::setStandardButtons

doesn't seem to have any effect; using the 'buttons' argument to the constructor does not work correctly. I may be doing something wrong.

+5


source







All Articles