替代 PyQt6 的 "QMessageBox.Yes"

Alternative to "QMessageBox.Yes" for PyQt6

我正在尝试将我的脚本从 PyQt5 移植到 PyQt6。由于 ,我已经弄清楚了如何移植大部分内容,但是,我 运行 遇到了问题。

我发现 PyQt6 使用 QtWidgets.QMessageBox.StandardButtons.Yes 而不是 PyQt5 的 QtWidgets.QMessageBox.Yes.

但是,当检查用户是否在 QMessageBox 打开后按下“是”时,将 QtWidgets.QMessageBox.Yes 替换为 QtWidgets.QMessageBox.StandardButtons.Yes 不起作用(检查下面的示例)。


示例:

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!")

打印“你好!”这里工作正常。 (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!")

“你好!”这里根本不打印。 (16384 != StandardButtons.yes)


我知道我可以做到:

x = reply.exec()

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

因为在按下“是”后,QMessageBox 等于 16384 (),但我想使用该方法,而是使用类似于 PyQt5 示例。

这有点奇怪。根据 QMessageBox.exec 的文档:

When using a QMessageBox with standard buttons, this function returns a StandardButton value indicating the standard button that was clicked.

您使用的是标准按钮,因此这应该 return 一个 QMessageBox.StandardButtons 枚举。

还值得一提的是,比较整数和枚举在 PyQt5 中不是问题,因为枚举是用 enum.IntEnum 实现的。现在,它们是用 enum.Enum 实现的。来自 Riverbank Computing website:

All enums are now implemented as enum.Enum (PyQt5 used enum.IntEnum for scoped enums and a custom type for traditional named enums). PyQt5 allowed an int whenever an enum was expected but PyQt6 requires the correct type.

但是,由于某些原因,QMessageBox.exec return 是一个整数(我只是用 PyQt6==6.0.0 试了一下)!

现在,您可以通过从 returned 整数有意构造一个枚举对象来解决这个问题:

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

而且,由于您要比较枚举,我建议使用 is 而不是 ==

QtWidgets.QMessageBox.StandardButtons 在 PyQt6 中使用 enum.Flag 实现,而 QDialog.exec() returns 和 int。遗憾的是这些不能直接比较,但你仍然可以使用:

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

请注意,惯用的 x == int(Yes) 也不起作用。

PyQt5 使用了包装的自定义 StandardButtons class(输入 Yes | No 以查看),而不是其他答案所声称的 enum.IntEnumIntEnum 本来是一个合乎逻辑的选择,因为它特别允许 int 比较。

我遇到了同样的问题(从 PyQt5 到 PyQt6)但是用这种方式编码是 运行 流畅的:

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

我用它作为 'critical' 或 'question' 甚至 'information' 它总是 运行

StandardButtons 不是 Attribute/Method 我可以为 QMessageBox 选择。不确定这是否可能在过去 4 个月内更新,但对我来说代码适用于 StandardButton 而不是 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!")

我知道答案可能有点晚了,但这是在 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() )

这种方式对我也很有帮助,主要是因为它已经翻译了按钮的文本。

    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()