![](/img/trans.png)
[英]How to cancel QProcess by clicking in QProgressDialog's cancel button?
[英]How to intercept QProgressDialog cancel click
我有一個帶有取消按鈕的標准 QProgressDialog。 如果/當用戶單擊取消按鈕時,我不希望對話框立即隱藏,相反我更願意禁用取消按鈕並執行一些清理工作,然后在確定這項工作后關閉 QProgressDialog已經完成。 如何攔截當前的function?
從文檔看來我應該覆蓋:
PySide.QtGui.QProgressDialog.cancel()
重置進度對話框。 PySide.QtGui.QProgressDialog.wasCanceled() 變為真,直到進度對話框被重置。 進度對話框將隱藏。
我已經嘗試子類化此方法,但當我單擊取消按鈕時它似乎甚至沒有被調用。
要禁用對話框的按鈕,您必須獲得對它的引用。 由於它是一個基本的 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 中收到通知,因此更合適的解決方案是在上面使用的子類中創建自定義信號:
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...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.