如何拦截QProgressDialog取消单击



我有一个带有取消按钮的标准QProgressDialog。如果/当用户单击取消按钮时,我不希望对话框立即隐藏,相反,我更希望禁用取消按钮并执行一些清理工作,然后在确定此工作完成后关闭QProgressDialog。如何截取当前函数?

从文档来看,我似乎应该重写:

PySide.QtGui.QProgressDialog.cancel()

重置进度对话框。PySide.QtGui.QProgressDialog.waseCanceled((变为true,直到重置进度对话框。进度对话框变得隐藏起来。

我尝试过对这个方法进行子类化,但当我单击取消按钮时,它似乎甚至没有被调用。

要禁用对话框的按钮,您必须获得对它的引用。由于它是一个基本的QPushButton,您可以使用findChild():

dialog = QProgressDialog(self)
cancelButton = dialog.findChild(QPushButton)
cancelButton.setEnabled(False)

考虑到从用户体验的角度来看,禁用一个永远不会启用的按钮是令人讨厌的,所以更好的选择是根本不显示它,setCancelButton()解释了如何做到这一点:

如果nullptr通过,则不会显示取消按钮。

在python术语中,nullptr表示None:

dialog = QProgressDialog(self)
dialog.setCancelButton(None)

不幸的是,这不会阻止用户通过关闭对话框或按Esc来取消对话框。

这对任何QDialog都有效,为了避免这种情况,子类化是更好的选择:您需要防止拒绝对话框(Esc键(关闭事件。虽然它们有相似的结果,但处理方式不同。

覆盖reject()(不执行任何操作(可防止任何可能触发拒绝(取消(的操作,包括按下Esc

重写closeEvent()需要一个额外的步骤:您必须确保事件是spontaneous()(由系统触发——通常情况下,用户按下窗口的关闭按钮(,并最终忽略它。这是必要的,因为您可能需要调用close()accept()实际在完成过程后关闭对话框。

class NonStopProgressDialog(QtWidgets.QProgressDialog):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setCancelButton(None)
def reject(self):
pass
def closeEvent(self, event):
if event.spontaneous():
event.ignore()

请注意,没有直接的方法可以知道自发关闭事件是由用户(试图关闭窗口(直接触发的,还是由系统(关闭时(触发的。

还要注意,如果确实需要以编程方式关闭对话框,则可以调用accept(),也可以调用基本实现,这样可以从对话框的reject():中获得正确的返回值

def rejectNoMatterWhat(self):
super().reject()

最后,如果出于任何原因,您仍然需要取消按钮,则必须断开其信号。

一般来说,这可能会起作用:

dialog = QProgressDialog(self)
cancelButton = dialog.findChild(QPushButton)
cancelButton.disconnect()

但上述操作会断开任何信号到任意插槽的连接,在某些情况下应避免这种情况
我们从来源中知道,clicked信号实际上连接到canceled()插槽,因此更好的解决方案是执行以下操作:

dialog = QProgressDialog(self)
cancelButton = dialog.findChild(QPushButton)
cancelButton.clicked.disconnect(self.canceled)

由于您可能需要在父类/主类中得到通知,因此更合适的解决方案是在上面使用的子类中创建一个自定义信号:

class NonStopProgressDialog(QtWidgets.QProgressDialog):
userCancel = QtCore.pyqtSignal()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
cancelButton = self.findChild(QPushButton)
cancelButton.clicked.disconnect(self.canceled)
cancelButton.clicked.connect(
lambda: cancelButton.setEnabled(False))
cancelButton.clicked.connect(self.userCancel)
def reject(self):
pass
def closeEvent(self, event):
if event.spontaneous():
event.ignore()
class SomeWindow(QtWidgets.QWidget):
def showProgress(self):
self.progressDialog = NonStopProgressDialog(self)
self.progressDialog.userCancel.connect(self.stopSomething)
# ...
def stopSomething(self):
self.progressDialog.setCancelButtonText('Please wait')
# do something...

相关内容

  • 没有找到相关文章

最新更新