当我在应用程序上单击“ 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_())
答案 0 :(得分:1)
您提供的代码存在一些问题。
首先,您不应在每次最小化窗口时创建新的系统任务栏图标。虽然可能使有意义,但这可能是一个问题,因为在某些平台(尤其是Windows)中,图标可能并不总是被“删除”(如“隐藏” )时,除非您明确将其删除(通常使用deleteLater()
)。
然后,尽管您说“该程序仍将成功关闭”,但可能不会。通常这取决于平台(不同的OS和OS版本),但这不是重点。
此外,由于您需要一种统一的方式来确保用户确实想要退出,因此您应该提供相应的方法来执行此操作,并因此对它的返回值做出反应,因为{{1 }}和触发的动作连接以不同的方式响应。
我已对您的代码进行了修改,统一了一种“ closeRequest”方法,该方法应能更好地响应用户交互。
一些注意事项。
无论何时使用“非标准” QWidget(例如QSystemTrayIcon),您都需要更好地控制程序实际退出的方式/时间,并且在设置QApplication.setQuitOnLastWindowClosed(bool)
时需要特别注意。
使用closeEvent
与os._exit
不相同:“ sys.exit
通常只应在fork()之后的子进程中使用“,这是(很少)并发事件循环的情况,例如将PyQt事件循环与PyGame一起使用(请参阅official docs)。
os._exit()
答案 1 :(得分:0)
找到了自己的解决方案,每当隐藏主程序时,关闭系统托盘中显示的消息框,整个程序也会关闭,
因此,添加app.setQuitOnLastWindowClosed(False)
以避免关闭MessageBox导致整个程序关闭。
最后,在closeEvent()中添加quit()