Используйте QMessageBox в PyQt5, чтобы перезапустить игру или выйти из приложения.

У меня есть игра памяти, сделанная в PyQt5. Когда пользователь выигрывает, я хотел бы показать сообщение с тремя вариантами (кнопками):

  1. 'играть снова'
  2. «обменять карты»
  3. 'покидать'

Я думаю, что способ реализовать это - использовать QMessageBox, но я не мог понять, как его правильно использовать. Я знаю, что это должно быть что-то вроде:

reply = QMessageBox.question(self,
    'title',
    'text',
    button1 | button2 | button3,
    defaultButton)

if reply == button1:
    # play again
elif reply == button2:
    # change cards
else:
    # close application

Я также знаю, что существуют StandardButtons, которые я могу использовать для выхода (QMessageBox.Close, но я не уверен), но я не знаю, как добавить их и другие пользовательские кнопки, чтобы они работали.

ИЗМЕНИТЬ 1

Хорошо, я думаю, что сделал несколько шагов в правильном направлении, хотя чего-то все еще не хватает. Я смог добавить пользовательские кнопки в свой QMessageBox, я могу print что-то сделать, когда одна из них нажата, но любой метод, который я вызываю после, ничего не делает. Кроме того, если выбрать «выход», он просто закроет окно сообщения (я использую метод QCloseEvent, возможно, это неправильно).

Вот обновленный код вместе с несколькими комментариями:

msgBox = QMessageBox()
msgBox.setStandardButtons(QMessageBox.Close)
restartBtn = msgBox.addButton('play again', QMessageBox.ActionRole)
changeBtn = msgBox.addButton('change cards', QMessageBox.ActionRole)

ret = msgBox.exec()

if ret == QMessageBox.Close:
    QCloseEvent() # should close the app, but it closes the message box
elif msgBox.clickedButton() == restartBtn:
    print('RESTART')
    self.restart # should call 'restart' method, but it doesn't
elif msgBox.clickedButton() == changeBtn:
    print('CHANGE')
    changeBtn.clicked.connect(self.showDialog) # should call 'showDialog' method, but it doesn't

Как видите, я пробовал и с self.methodname, и с button.clicked.connect(self.methodname), но ни один не работал.


person umbe1987    schedule 20.10.2016    source источник


Ответы (3)


Кажется, вы уже разобрались с большей частью этого, но вот полный пример:

def showMessageBox(self):
    msg = QtWidgets.QMessageBox(self)
    msg.setIcon(QtWidgets.QMessageBox.Question)
    msg.setWindowTitle('Prompt')
    msg.setText('Please choose an option:')
    play = msg.addButton(
        'Play Again', QtWidgets.QMessageBox.AcceptRole)
    change = msg.addButton(
        'Change Cards', QtWidgets.QMessageBox.AcceptRole)
    quit = msg.addButton(
        'Quit', QtWidgets.QMessageBox.RejectRole)
    msg.setDefaultButton(play)
    msg.exec_()
    msg.deleteLater()
    if msg.clickedButton() is play:
        print('RESTART')
        self.restart()
    elif msg.clickedButton() is change:
        print('CHANGE')
        self.showDialog()
    else:
        self.close()
person ekhumoro    schedule 20.10.2016
comment
Принято, поскольку он завершает мой собственный ответ. Спасибо (еще раз)! - person umbe1987; 20.10.2016

Наконец я понял, что то, что я делал, было почти правильным, за исключением того, что после вызова методов не было скобки. Теперь код работает нормально, за исключением того факта, что он не выходит из приложения при нажатии «выход» (только окно сообщения), но я обновлю свой ответ, как только найду способ. Надеюсь, это может стать хорошим примером для всех, кто хочет реализовать свой собственный QMessageBox.

И последнее замечание: оба способа, которые я пробовал, а именно вызов самого метода или вызов его с помощью префикса метода button.clicked.connect(), сработали для меня. Может быть, один лучше другого, но я сужу.

msgBox = QMessageBox()
msgBox.setStandardButtons(QMessageBox.Close)
restartBtn = msgBox.addButton('play again', QMessageBox.ActionRole)
changeBtn = msgBox.addButton('change cards', QMessageBox.ActionRole)

ret = msgBox.exec()

if ret == QMessageBox.Close:
    QCloseEvent() # should close the app, but it closes the message box
elif msgBox.clickedButton() == restartBtn:
    print('RESTART')
    self.restart()
elif msgBox.clickedButton() == changeBtn:
    print('CHANGE')
    changeBtn.clicked.connect(self.showDialog())
person umbe1987    schedule 20.10.2016

self.close работает как метод закрытия всего приложения.

button.clicked.connect(self.close)

choice = QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Quit)

if choice == QtGui.QMessageBox.Quit:
        self.close()
person rainer    schedule 23.10.2016