[英]self.close() will close the program even though closeEvent() has self.ignore() inside
當我在應用程序上單擊“X”並從 MessageBox 中按“否”時,程序將不會關閉。 但是當我隱藏程序並從系統托盤的菜單中單擊“退出”並從消息框中單擊“否”時,該程序仍將成功關閉....
我的代碼是這樣的:
exitAction = menu.addAction("Quit")
exitAction.triggered.connect(self.close)
那么我的 closeEvent() 代碼是:
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Quit', 'Are You Sure to Quit?', QMessageBox.No | QMessageBox.Yes)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
編輯:我意識到每當菜單彈出 QMessageBox 時,無論我選擇哪個選項,整個程序仍將關閉,我認為可能是這個問題?:
os._exit(app2.exec_())
我在消息框之前添加了self.show()並且它可以工作,有沒有辦法讓它在沒有 self.show() 的情況下工作? 因為我允許用戶在程序隱藏時從系統托盤退出程序
def closeEvent(self, event):
self.show() << I added this and it works
reply = QMessageBox.question(self, 'Quit', 'Are You Sure to Quit?', QMessageBox.No | QMessageBox.Yes)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
可重現的代碼:
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUi()
def initUi(self):
self.resize(350, 150)
self.setWindowTitle("Test")
pb_min = QPushButton("Minimise the Program", self)
pb_min.clicked.connect(self.pbMin)
h_box = QHBoxLayout()
h_box.addStretch()
h_box.addWidget(pb_min)
h_box.addStretch()
self.setLayout(h_box)
def pbMin(self):
menu = QMenu()
showAction = menu.addAction('Show')
showAction.triggered.connect(self.showGUI)
exitAction = menu.addAction("Quit")
exitAction.triggered.connect(self.close)
self.hide()
self.mSysTrayIcon = QSystemTrayIcon(self)
icon = QIcon("test.png")
self.mSysTrayIcon.setIcon(icon)
self.mSysTrayIcon.setContextMenu(menu)
self.mSysTrayIcon.setToolTip("Show Test")
self.mSysTrayIcon.activated.connect(self.onActivated)
self.mSysTrayIcon.show()
def showGUI(self):
self.show()
self.mSysTrayIcon.hide()
def onActivated(self, reason):
if reason == self.mSysTrayIcon.Trigger:
self.show()
self.mSysTrayIcon.hide()
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Quit', 'Are You Sure to Quit?', QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
os._exit(app.exec_())
您提供的代碼存在一些問題。
首先,您不應該每次最小化窗口時都創建一個新的系統托盤圖標; 雖然它可能有一定的意義,但它可能是一個問題,因為在某些平台(特別是 Windows)中,當您創建一個新圖標時,該圖標可能不會總是被“刪除”(如“隱藏”),除非您明確刪除它(通常使用deleteLater()
)。
然后,當您說“程序仍將成功關閉”時,它可能不會。 這通常取決於平台(不同的操作系統和操作系統版本),但這不是重點。
此外,由於您需要一種統一的方式來確保用戶真的想退出,您應該提供相應的方法來做到這一點,從而對其返回值做出反應,因為closeEvent
和觸發的操作連接以不同的方式響應。
我已經修改了您的代碼,統一了一個“closeRequest”方法,可以更好地對用戶交互做出反應。
一些注意事項。
每當您使用“非標准”QWidget(例如 QSystemTrayIcon)時,您都需要更好地控制程序實際退出的方式/時間,並且在設置QApplication.setQuitOnLastWindowClosed(bool)
需要特別小心。
使用os._exit
是不一樣的sys.exit
:“ os._exit()
應通常只在子進程叉()之后使用”,這是並發事件循環,如使用的(很少)的情況下PyQt 事件循環以及 PyGame 事件循環(請參閱官方文檔)。
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUi()
def initUi(self):
self.resize(350, 150)
self.setWindowTitle("Test")
pb_min = QPushButton("Minimise the Program", self)
pb_min.clicked.connect(self.pbMin)
h_box = QHBoxLayout()
h_box.addStretch()
h_box.addWidget(pb_min)
h_box.addStretch()
self.setLayout(h_box)
menu = QMenu()
showAction = menu.addAction('Show')
showAction.triggered.connect(self.showGUI)
exitAction = menu.addAction("Quit")
exitAction.triggered.connect(self.quitRequest)
self.mSysTrayIcon = QSystemTrayIcon(self)
icon = QIcon("test.png")
self.mSysTrayIcon.setIcon(icon)
self.mSysTrayIcon.setContextMenu(menu)
self.mSysTrayIcon.setToolTip("Show Test")
self.mSysTrayIcon.activated.connect(self.onActivated)
def pbMin(self):
self.hide()
self.mSysTrayIcon.show()
def showGUI(self):
self.show()
self.mSysTrayIcon.hide()
def onActivated(self, reason):
if reason == self.mSysTrayIcon.Trigger:
self.show()
self.mSysTrayIcon.hide()
def quitRequest(self):
if self.closeRequest():
QApplication.quit()
def closeRequest(self):
reply = QMessageBox.question(self, 'Quit', 'Are You Sure to Quit?', QMessageBox.Yes | QMessageBox.No)
return reply == QMessageBox.Yes
def closeEvent(self, event):
if self.closeRequest():
event.accept()
QApplication.quit()
else:
event.ignore()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
ex = Example()
ex.show()
sys.exit(app.exec_())
找到我自己的解決方案,每當隱藏主程序時,系統托盤顯示的messagebox一旦關閉,整個程序也會關閉,因此添加app.setQuitOnLastWindowClosed(False)
以避免關閉MessageBox導致整個程序關掉。
最后,在 closeEvent() 中添加quit()
()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.