Python 如何在显示主窗口之前退出Qt应用程序
启动时,在显示主窗口之前,我的Qt应用程序会显示一个带有一些选项的对话框。该对话框具有“开始”和“取消”按钮。稍后,当用户单击“新建游戏”按钮时,在显示主窗口后,将使用相同的对话框 我试图让“取消”按钮退出应用程序,如果它是唯一显示的界面元素(即在应用程序启动时)。但是,在我当前的代码中,主窗口仍然显示 如果我用Python 如何在显示主窗口之前退出Qt应用程序,python,pyside2,Python,Pyside2,启动时,在显示主窗口之前,我的Qt应用程序会显示一个带有一些选项的对话框。该对话框具有“开始”和“取消”按钮。稍后,当用户单击“新建游戏”按钮时,在显示主窗口后,将使用相同的对话框 我试图让“取消”按钮退出应用程序,如果它是唯一显示的界面元素(即在应用程序启动时)。但是,在我当前的代码中,主窗口仍然显示 如果我用self.view.deleteLater()替换self.view.destroy(),主窗口会在消失之前短暂闪烁(并正确退出),但这不是解决方案 如果我将视图.show()调用移动到
self.view.deleteLater()
替换self.view.destroy()
,主窗口会在消失之前短暂闪烁(并正确退出),但这不是解决方案
如果我将视图.show()
调用移动到对话框.exec()块中,它也不会工作。主要是因为每次从主窗口再次显示对话框时,我都会调用view.show()
,但也因为即使在这种情况下,应用程序也不会真正退出。在本例中,主窗口不显示,但进程保持运行(Python应用程序图标在Dock中仍然可见)
我做错了什么?我读过,但不明白如何将这些解决方案应用到我的案例中
(macOS 10.15.6上的PySide2 5.15.1)
如果代码分析得很好,就会发现在eventloop启动之前调用了“quit”,因此终止从未启动的eventloop是没有意义的。解决方案是在eventloop启动后立即调用X。另一方面,quit方法是静态的,因此不需要访问“self.app”
非常感谢。在我看来,将QApplication对象传递给应用程序控制器确实很奇怪。但是,当我修改代码以反映您的代码时,根本不会显示对话框。我不明白为什么。@Cirroculus 1)这个应用程序是无关紧要的,因为它是一个风格问题。2) 我已经提供了一个实现您所要求的功能代码,我不负责它的实现,因为我不知道它。因此,如果您需要更多帮助,那么请提供一个解决方案,因为您不想显示的代码可能正在生成错误。您是正确的,您的建议揭示了另一个奇怪的问题,即我如何绑定按钮。这是一个无关的问题。再次感谢。
class App:
def __init__(self, app, game, view):
self.app = app
self.game = game
self.view = view
# Display the dialog
# Same callback is bound to a QPushButton in MainWindow
self.cb_start_dialog()
def cb_start_dialog(self):
# Do some initialisation
dialog = DialogNewGame() # A subclass of QDialog
if dialog.exec_():
# Setup the interface
else:
if not self.view.isVisible():
# Condition evaluates correctly
# (False on app launch,
# True if main window is displayed)
self.view.destroy()
self.app.quit() # Doesn't work, main window still displayed
def main():
application = QApplication()
view = MainWindow() # A QWidget with the main window
model = Game() # Application logic
App(application, model, view)
view.show()
application.exec_()
from PySide2.QtCore import QTimer
from PySide2.QtWidgets import QApplication, QDialog, QMainWindow
class MainWindow(QMainWindow):
pass
class DialogNewGame(QDialog):
pass
class Game:
pass
class App:
def __init__(self, game, view):
self.game = game
self.view = view
QTimer.singleShot(0, self.cb_start_dialog)
def cb_start_dialog(self):
dialog = DialogNewGame()
if dialog.exec_():
pass
else:
QApplication.quit()
def main():
application = QApplication()
view = MainWindow()
model = Game()
app = App(model, view)
view.show()
application.exec_()
if __name__ == "__main__":
main()