'Alternative to "QMessageBox.Yes" for PyQt6

I am trying to port over a script of mine from PyQt5 to PyQt6. I have figured out how to port most of the things thanks to this answer, however, I have run into an issue.

I have figured out that PyQt6 uses QtWidgets.QMessageBox.StandardButtons.Yes instead of PyQt5's QtWidgets.QMessageBox.Yes.

However, when checking if the user pressed "Yes" after a QMessageBox opens, replacing QtWidgets.QMessageBox.Yes with QtWidgets.QMessageBox.StandardButtons.Yes doesn't work (check the examples below).


Examples:

PyQt5:

reply = QtWidgets.QMessageBox()
reply.setText("Some random text.")
reply.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)

x = reply.exec_()

if x == QtWidgets.QMessageBox.Yes:
    print("Hello!")

Printing "Hello!" here works normally. (16384 == 16384)

PyQt6:

reply = QtWidgets.QMessageBox()
reply.setText("Some random text.")
reply.setStandardButtons(QtWidgets.QMessageBox.StandardButtons.Yes | 
                         QtWidgets.QMessageBox.StandardButtons.No)

x = reply.exec()

if x == QtWidgets.QMessageBox.StandardButtons.Yes:
    print("Hello!")

"Hello!" here doesn't print at all. (16384 != StandardButtons.yes)


I know I could just do:

x = reply.exec()

if x == 16384:
    print("Hello!")

because, after pressing "Yes", the QMessageBox equals to 16384 (see this), but I'd like to not use that approach, and rather use something like the PyQt5 example.



Solution 1:[1]

StandardButtons is not an Attribute/Method I can choose for QMessageBox. Not sure if this was maybe updated in the last 4 months, but for me the code works with StandardButton instead of StandardButtons.

from PyQt6.QtWidgets import QMessageBox

reply = QMessageBox()
reply.setText("Some random text.")
reply.setStandardButtons(QMessageBox.StandardButton.Yes | 
                     QMessageBox.StandardButton.No)

x = reply.exec()

if x == QMessageBox.StandardButton.Yes:
    print("Hello!")

Solution 2:[2]

QtWidgets.QMessageBox.StandardButtons are implemented using enum.Flag in PyQt6, while QDialog.exec() returns an int. Sadly these cannot be directly compared, but you can still use:

if x == QtWidgets.QMessageBox.StandardButtons.Yes.value:
    print("Hello!")

Note that the idiomatic x == int(Yes) does not work either.

PyQt5 used a wrapped custom StandardButtons class (type in Yes | No to see this), NOT an enum.IntEnum as the other answer is claiming. An IntEnum would have been a logical choice however since it specifically allows int comparisons.

Solution 3:[3]

I had the same problem (from PyQt5 to PyQt6) but coding in this way it's running smooth:

if QtWidgets.QMessageBox.critical(self,"Foo","PROTECTION NOT FOUND - Exit",QtWidgets.QMessageBox.StandardButtons.Yes):
                print("Exit")

I used it as 'critical' or 'question' and even 'information' and it's always running

Solution 4:[4]

I know the answer might be a little late, but here's what works for me in pyqt6.

msg = QMessageBox()
msg.setIcon(QMessageBox.Icon.Information)

msg.setText('Teste')
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
#msg.setDetailedText("The details are as follows:")
msg.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel)
msg.buttonClicked.connect(self.msgbtn)
msg.exec()

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

Solution 5:[5]

This way it also served me very well, mainly because it already translates the text of the button.

    msgBox = QMessageBox()
    msgBox.setIcon(QMessageBox.Icon.Information)
    msgBox.setWindowTitle('Excluir Ponto')
    msgBox.setText('Tem certeza que deseja excluir o ponto {point}?'.format(point = self.dialogCUDP.UI.lineEditPoint.text()))
    btn_delete = msgBox.addButton('Excluir', QMessageBox.ButtonRole.YesRole)
    btn_cancel = msgBox.addButton('Cancelar', QMessageBox.ButtonRole.NoRole)
    msgBox.exec()

    if msgBox.clickedButton() == btn_delete:
        if self._serverOn:
            if self.GM.dfPointsManager.deletePointPMCSV(Priceformat.setFormatStrFloat(self.dialogCUDP.UI.lineEditPoint.text())):
                QMessageBox.information(self, 'Excluir Ponto', 'Ponto {point}, excluído com sucesso!'.format(point = self.dialogCUDP.UI.lineEditPoint.text()))
                self.disableFieldCUDPoint()
                self.clearFieldCUDPoint()
            else:
                QMessageBox.warning(self, 'Excluir Ponto', 'Não foi possível excluir o ponto {point}!\nPor favor, tente novamente'.format(point = self.dialogCUDP.UI.lineEditPoint.text()))
                msgBox.close()
        else:
            if self._createnewpointPM.deletePointPMCSV(Priceformat.setFormatStrFloat(self.dialogCUDP.UI.lineEditPoint.text())):
                QMessageBox.information(self, 'Excluir Ponto', 'Ponto {point}, excluído com sucesso!'.format(point = self.dialogCUDP.UI.lineEditPoint.text()))
                self.disableFieldCUDPoint()
                self.clearFieldCUDPoint()
            else:
                QMessageBox.warning(self, 'Excluir Ponto', 'Não foi possível excluir o ponto {point}!\nPor favor, tente novamente'.format(point = self.dialogCUDP.UI.lineEditPoint.text()))
                msgBox.close()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sebastian
Solution 2 xjcl
Solution 3 Roshin Raphel
Solution 4 Luis Chaves
Solution 5 Luis Chaves