PyQt: QMessageBox Duplication

在使用 PyQt 的 QMessageBox 时,如果你遇到 消息框重复显示QMessageBox 重复实例化 的问题,通常是因为消息框没有正确管理或关闭,或者消息框的创建和显示逻辑中存在重复调用。以下是一些常见原因和解决方案。

在这里插入图片描述

1、问题背景

在 PyQt 中使用 QMessageBox 时,发现了一个重复的问题。当用户在回答问题时,会弹出一个确认消息框。然而,当用户确认并继续下一个问题时,会有 2 个消息框弹出,然后是 3 个,以此类推。

以下代码描述了该问题:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class IntegrationQuestions(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle('Integration')
        self.setMinimumSize(265,400)
        self.setMaximumSize(266,401)
        self.Question1()

    def Question1(self):
        # 从另一个文件中获取问题
        from FQuestions import FIntQuestion, FIntAnswer

        self.lbl1 = QtGui.QLabel("Integrate the equation below",self)
        self.lbl1.move(0,0)
        self.lbl1.resize(200,20)

        self.lbl2 = QtGui.QLabel(pretty(FIntQuestion[0], use_unicode = False), self)
        self.lbl2.resize(200, 80)
        self.lbl2.move(30,30)

        self.lbl3 = QtGui.QLabel("Sketch pad",self)
        self.lbl3.move(0,120)

        # 用户可以用来演算的自由区域
        self.SketchPad = QtGui.QTextEdit(self)
        self.SketchPad.resize(250,150)
        self.SketchPad.move(0,150)

        self.lbl4 = QtGui.QLabel("Answer",self)
        self.lbl4.move(0,300)

        # 用户输入的答案
        self.Answer = QtGui.QLineEdit(self)
        self.Answer.move(0,330)
        self.Answer.resize(250,20)

        self.next_question = QtGui.QPushButton('Next', self)
        self.next_question.move(160,360)

        # 连接按钮的单击事件和处理问题1的方法
        self.next_question.clicked.connect(self.HandleQuestion1)

        # 用于存储用户回答所有问题后的分数
        self.score = 0

        # 用于测试
        print(FIntAnswer[0])

    def HandleQuestion1(self):
        from FQuestions import FIntAnswer

        # 弹出确认消息框,询问用户是否确认答案
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure this is your final answer?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)

        # 如果用户确认答案,则检查答案是否正确
        if reply == QtGui.QMessageBox.Yes:
            if self.Answer.text() == FIntAnswer[0]:
                self.score += 1
            else:
                self.score += 0

            # 如果用户确认,则继续下一个问题
            self.Question2()

    def Question2(self):
        from FQuestions import FIntQuestion, FIntAnswer

        # 更新问题文本
        self.lbl2.setText(pretty(FIntQuestion[1], use_unicode = False))

        # 连接按钮的单击事件和处理问题2的方法
        self.next_question.clicked.connect(self.HandleQuestion2)

        # 用于测试
        print(FIntAnswer[1])

    def HandleQuestion2(self):
        from FQuestions import FIntAnswer

        # 弹出确认消息框,询问用户是否确认答案
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure this is your final answer?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)

        # 如果用户确认答案,则检查答案是否正确
        if reply == QtGui.QMessageBox.Yes:
            if self.Answer.text() == FIntAnswer[1]:
                self.score += 1
            else:
                self.score += 0

            # 如果用户确认,则继续下一个问题
            self.Question3()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = IntegrationQuestions()
    window.show()
    sys.exit(app.exec_())

当用户回答第一个问题并单击“Next”按钮时,会弹出一个消息框询问是否确认答案。如果用户确认,则会继续下一个问题。然而,当用户回答第二个问题并单击“Next”按钮时,会出现两个消息框,其中一个是第一个问题的确认消息框,另一个是第二个问题的确认消息框。以此类推,每回答一个问题,就会出现一个新的消息框。

2、解决方案

要解决这个问题,需要在连接新方法之前断开以前连接的信号。例如,在 HandleQuestion2 方法中,可以先断开 next_question 按钮与 HandleQuestion1 方法的连接,然后再将其与 HandleQuestion2 方法连接。

    # 断开按钮与处理问题1方法的连接
    self.next_question.clicked.disconnect(self.HandleQuestion1)

    # 连接按钮与处理问题2方法
    self.next_question.clicked.connect(self.HandleQuestion2)

这样,当用户回答第二个问题并单击“Next”按钮时,只会弹出一个消息框询问是否确认答案,而不会出现两个消息框。

以下代码展示了修正后的代码:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class IntegrationQuestions(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle('Integration')
        self.setMinimumSize(265,400)
        self.setMaximumSize(266,401)
        self.Question1()

    def Question1(self):
        # 从另一个文件中获取问题
        from FQuestions import FIntQuestion, FIntAnswer

        self.lbl1 = QtGui.QLabel("Integrate the equation below",self)
        self.lbl1.move(0,0)
        self.lbl1.resize(200,20)

        self.lbl2 = QtGui.QLabel(pretty(FIntQuestion[0], use_unicode = False), self)
        self.lbl2.resize(200, 80)
        self.lbl2.move(30,30)

        self.lbl3 = QtGui.QLabel("Sketch pad",self)
        self.lbl3.move(0,120)

        # 用户可以用来演算的自由区域
        self.SketchPad = QtGui.QTextEdit(self)
        self.SketchPad.resize(250,150)
        self.SketchPad.move(0,150)

        self.lbl4 = QtGui.QLabel("Answer",self)
        self.lbl4.move(0,300)

        # 用户输入的答案
        self.Answer = QtGui.QLineEdit(self)
        self.Answer.move(0,330)
        self.Answer.resize(250,20)

        self.next_question = QtGui.QPushButton('Next', self)
        self.next_question.move(160,360)

        # 连接按钮的单击事件和处理问题1的方法
        self.next_question.clicked.connect(self.HandleQuestion1)

        # 用于存储用户回答所有问题后的分数
        self.score = 0

        # 用于测试
        print(FIntAnswer[0])

    def HandleQuestion1(self):
        from FQuestions import FIntAnswer

        # 弹出确认消息框,询问用户是否确认答案
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure this is your final answer?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)

        # 如果用户确认答案,则检查答案是否正确
        if reply == QtGui.QMessageBox.Yes:
            if self.Answer.text() == FIntAnswer[0]:
                self.score += 1
            else:
                self.score += 0

            # 断开按钮与处理问题1方法的连接
            self.next_question.clicked.disconnect(self.HandleQuestion1)

            # 如果用户确认,则继续下一个问题
            self.Question2()

    def Question2(self):
        from FQuestions import FIntQuestion, FIntAnswer

        # 更新问题文本
        self.lbl2.setText(pretty(FIntQuestion[1], use_unicode = False))

        # 连接按钮的单击事件和处理问题2的方法
        self.next_question.

通过上面这些方法,我们就可以避免 QMessageBox 的重复显示问题,并确保应用的对话框逻辑运行顺畅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值