Close Event 不叫 Keyboard Event 和 MessageBox

Close Event are not called Keyboard Event and MessageBox

我使用 QT Designer 进行 GUI 编程,并希望使用 ESC 键禁用关闭事件。用户可以使用顶部的 X 关闭应用程序,但不能使用任何键。

函数 closeEvent(self,event) 不工作。

def closeEvent(self, event):
    close = QMessageBox()
    close.setText("You sure?")
    close.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel)
    close = close.exec()

    if close == QMessageBox.Yes:
        event.accept()
    else:
        event.ignore()

函数在我的主class: class Ui_Tool(object)

class Ui_LabelTool(object):
def setupUi(self, LabelTool):
    Tool.setObjectName("Tool")
    Tool.resize(650, 569)
    Tool.setMinimumSize(QtCore.QSize(650, 569))
    Tool.setMaximumSize(QtCore.QSize(650, 569))
    Tool.setAutoFillBackground(False)
    Tool.setSizeGripEnabled(False)
    ...

    #Events for Buttons
    self.SelectFolder.clicked.connect(self.setfolder)   
    self.SelectOutputFolder.clicked.connect(self.SetOutputFolder)       
    self.LoadeMeasurement.clicked.connect(self.LoadRecording)           
    self.StartButton.clicked.connect(self.startProcessing)              
    self.Next_btn.clicked.connect(self.nextOperation)                   
    self.Prev_Btn.clicked.connect(self.prefOperation)                   
    self.Reset_btn.clicked.connect(self.resetApp)

    self.treeView.clicked.connect(self.ClickMeasurement) 
    self.treeWidget.clicked.connect(self.CheckTopicSelect)              

    self.horizontalSlider.valueChanged.connect(self.SliderValueChange)
    self.horizontalSlider.sliderMoved.connect(self.dispSlider)

    self.BBObject_btn.clicked.connect(self.CreateBBObj)
    self.BBNoObject_btn.clicked.connect(self.CreateBBNoObj)

    self.ShowAll_btn.clicked.connect(self.SaveImages)

def retranslateUi(self, LabelTool):
    _translate = QtCore.QCoreApplication.translate
    Tool.setWindowTitle(_translate("Tool", "Tool"))
    self.LoadeMeasurement.setText(_translate("Tool", "Load Measurement"))
    self.StartButton.setText(_translate("Tool", "Start "))
    self.Reset_btn.setText(_translate("Tool", "Reset"))
    self.Header_lbl.setText(_translate("Tool", "Test"))
    ...

这是我的主要功能:

if __name__ == "__main__":

    import sys
    app = QtWidgets.QApplication(sys.argv)
    Tool = QtWidgets.QDialog()
    ui = Ui_Tool()
    ui.setupUi(Tool)
    Tool.show()
    sys.exit(app.exec_())

我做错了什么?

我添加以下内容class:

class Logic(QMainWindow, Ui_Tool):
def __init__(self, *args, **kwargs):
    QMainWindow.__init__(self, *args, **kwargs)
    self.setupUi(self)

def closeEvent(self, event):
    answer = QtWidgets.QMessageBox.question(
        self,
        'Are you sure you want to quit ?',
        'Task is in progress !',
        QtWidgets.QMessageBox.Yes,
        QtWidgets.QMessageBox.No)
    if answer == QtWidgets.QMessageBox.Yes:
        event.accept()
    else:
        event.ignore()

如果the docs被审核:

Escape Key

If the user presses the Esc key in a dialog, QDialog::reject() will be called. This will cause the window to close: The close event cannot be ignored.

所以有两种可能的解决方案:

  1. 覆盖keyPressEvent()方法,当你按下escape键时,调用close()。

  2. 覆盖 reject() 方法来验证 QMessageBox 并根据它制定逻辑。

除此实现外,您必须在小部件中执行此操作,而不是在 Qt Designer(1) 生成的 class 中执行,考虑到上述实现两种解决方案都是:

1.

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_LabelTool(object):
    def setupUi(self, Tool):
        Tool.setObjectName("Tool")
        Tool.resize(650, 569)
        Tool.setMinimumSize(QtCore.QSize(650, 569))
        Tool.setMaximumSize(QtCore.QSize(650, 569))
        Tool.setAutoFillBackground(False)
        Tool.setSizeGripEnabled(False)
        # ....


class LabelTool(QtWidgets.QDialog, Ui_LabelTool):
    def __init__(self, parent=None):
        super(LabelTool, self).__init__(parent)
        self.setupUi(self)

    def verify_by_user(self):
        answer = QtWidgets.QMessageBox.question(
            self,
            "Are you sure you want to quit ?",
            "Task is in progress !",
            QtWidgets.QMessageBox.Yes,
            QtWidgets.QMessageBox.No,
        )
        return answer == QtWidgets.QMessageBox.Yes

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.close()
        else:
            super(LabelTool, self).keyPressEvent(event)

    def closeEvent(self, event):
        if self.verify_by_user():
            event.accept()
        else:
            event.ignore()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = LabelTool()
    w.show()
    sys.exit(app.exec_())

2.

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_LabelTool(object):
    def setupUi(self, Tool):
        Tool.setObjectName("Tool")
        Tool.resize(650, 569)
        Tool.setMinimumSize(QtCore.QSize(650, 569))
        Tool.setMaximumSize(QtCore.QSize(650, 569))
        Tool.setAutoFillBackground(False)
        Tool.setSizeGripEnabled(False)
        # ....


class LabelTool(QtWidgets.QDialog, Ui_LabelTool):
    def __init__(self, parent=None):
        super(LabelTool, self).__init__(parent)
        self.setupUi(self)

    def verify_by_user(self):
        answer = QtWidgets.QMessageBox.question(
            self,
            "Are you sure you want to quit ?",
            "Task is in progress !",
            QtWidgets.QMessageBox.Yes,
            QtWidgets.QMessageBox.No,
        )
        return answer == QtWidgets.QMessageBox.Yes

    def reject(self):
        if self.verify_by_user():
            super(LabelTool, self).reject()

    def closeEvent(self, event):
        if self.verify_by_user():
            event.accept()
        else:
            event.ignore()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = LabelTool()
    w.show()
    sys.exit(app.exec_())

(1) Using the Generated Code