pyqt5 python:如何在同一对话框上单击 "retry" 按钮时保持打开对话框

pyqt5 python: how to keep open dialog box when clicking "retry" button on same dialog

有没有什么方法可以在单击其中一个按钮后重试首先打开此框的 IF 语句后使对话框保持打开状态? 我想在不关闭此对话框的情况下,在达到条件后继续单击“重试”按钮...否则,您能告诉我如何实现此功能吗?

import random
import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        button = QPushButton("Press me for a dialog!")
        button.clicked.connect(self.button_clicked)
        self.setCentralWidget(button)

    def button_clicked(self):
        self.rand = random.uniform(0, 1)
        print(self.rand)
        if self.rand > 0.5:
            self.critical = QMessageBox.critical(
            self,
            "Oh no!",
            "Something went very wrong.",
            buttons=QMessageBox.Retry | QMessageBox.Cancel,
            defaultButton=QMessageBox.Retry)
            if self.critical == QMessageBox.Retry:
                print("Retry!")
                self.rand = random.uniform(0, 1)
                print(self.rand)
            else:
                print("Cancel!")
        
        else:
            self.ok = QMessageBox(self)
            self.ok.setWindowTitle("All good!")
            self.ok.setText("Everything looks perfect!")
            self.button = self.ok.exec()
    
            if self.button == QMessageBox.Ok:
                print("OK!")
            

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

非常感谢!

QMessageBox 的静态函数自动连接它的按钮,所以你只有两个选择:你要么使用 while 循环并在每次值无效且回复按钮被按下时创建一个 QMessageBox,要么你创建一个 QMessageBox 实例并断开其默认信号。

基本 while 循环

这是最简单的解决方案:一个 while 循环,不断显示消息框,直到值有效;缺点是你不能重复使用现有的对话框,并且总是会显示一个新的对话框;

    def button_clicked(self):
        self.rand = random.uniform(0, 1)
        print(self.rand)
        if self.rand > 0.5:
            while self.rand > 0.5:
                self.critical = QMessageBox.critical(
                self,
                "Oh no!",
                "Something went very wrong.",
                buttons=QMessageBox.Retry | QMessageBox.Cancel,
                defaultButton=QMessageBox.Retry)
                if self.critical == QMessageBox.Retry:
                    print("Retry!")
                    self.rand = random.uniform(0, 1)
                    print(self.rand)
                else:
                    print("Cancel!")
                    break
        # ...

使用 QMessageBox 实例

这有点复杂,但也更一致。您需要创建一个新的 QMessageBox 实例,断开其按钮框的 clicked 信号(这是 QMessageBox 用来决定如何设置其 finished 值的信号),而是连接其 acceptedrejected 信号;后者将取消对话,而前者将调用一个生成新值的本地函数,如果对话有效则最终接受该对话:

    def button_clicked(self):
        self.rand = random.uniform(0, 1)
        if self.rand > 0.5:
            def checkRand():
                self.rand = random.uniform(0, 1)
                if self.rand > 0.5:
                    msgBox.accept()
                    print('OK!')
                else:
                    print(self.rand)

            msgBox = QMessageBox(
                QMessageBox.Critical, 
                "Oh no!", 
                "Something went very wrong.", 
                buttons=QMessageBox.Retry | QMessageBox.Cancel, 
                parent=self
                )
            buttonBox = msgBox.findChild(QDialogButtonBox)
            buttonBox.clicked.disconnect()
            buttonBox.rejected.connect(msgBox.reject)
            buttonBox.accepted.connect(checkRand)
            msgBox.exec_()
        # ...