PyQt5 无需点击任何按钮或点击任何内容即可终止应用程序
Posted
技术标签:
【中文标题】PyQt5 无需点击任何按钮或点击任何内容即可终止应用程序【英文标题】:PyQt5 Terminate the app without hitting any button or clicking on anything 【发布时间】:2020-06-17 12:10:38 【问题描述】:import sys
from PyQt5.QtWidgets import (QMainWindow, QLabel, QGridLayout, qApp,
QApplication, QWidget, QPushButton)
from PyQt5.QtCore import QSize, Qt
class HelloWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Hello world")
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
title = QLabel("Hello World from PyQt")
title.setAlignment(Qt.AlignCenter) # <---
gridLayout = QGridLayout(centralWidget)
gridLayout.addWidget(title, 0, 0)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
mainWin.close()
app.quit()
sys.exit( app.exec_() )
我希望应用程序“自动”关闭(无需点击任何按钮或单击“x”)。我试过close()
和app.quit()
但是它只是关闭了窗口。该应用程序仍在运行。
你能帮我解决这个问题吗?
【问题讨论】:
什么是Game
?它有什么作用? for 循环中会发生什么?请提供minimal, reproducible example。
@musicamante 事实上,我认为游戏的本质,以及循环中发生的事情是不相关的,因为我寻求一些通用的解决方案(可能是一些功能)来关闭应用程序一旦我不再需要它(在这种情况下,在循环执行之后)。因此,我只是没有明确提及这些事情。但是,如果这些信息有帮助,那么游戏就是使用 PyQt5 创建的应用程序。在循环中,我正在收集有关游戏状态的一些数据。
Game
做了什么以及循环中可能发生的事情是相关的,并且很多。你说Game
是“使用 PyQt5 创建的应用程序”,但是一个“应用程序”已经存在(QApplication 实例),所以我只能假设你的意思是一些 QWidget应该做某事的基于 UI 的用户界面。然后,从您的代码看来,generate_data
似乎是一个类的一部分,我们不知道它是什么类型的类,它做什么,也不知道它是如何创建的。请按照已要求提供 MRE。
@musicamante 不幸的是,我不知道如何将它压缩成一个可重复的小例子,因为有不同的类相互连接。我只能说我做了什么。 Game() 正在启动 UI,它是 QMainWindow 的祖先,主窗口上有一些小部件。在循环中,我调用了一个函数 make_a_step() 来移动一个粒子,并且我将该粒子的坐标存储在一个列表中。完成这些步骤后,我希望应用程序自行关闭,而无需点击任何按钮或单击任何位置。
那么只需要close
窗口就足够了:默认情况下,一旦关闭最后一个Qt窗口,QApplication就会自动退出(意味着app.exec()
返回)。
【参考方案1】:
我想我找到了解决办法。像这样修改鳕鱼给出了想要的答案
import sys
from PyQt5.QtWidgets import (QMainWindow, QLabel, QGridLayout, qApp,
QApplication, QWidget, QPushButton)
from PyQt5.QtCore import QSize, Qt
class HelloWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Hello world")
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
title = QLabel("Hello World from PyQt")
title.setAlignment(Qt.AlignCenter) # <---
gridLayout = QGridLayout(centralWidget)
gridLayout.addWidget(title, 0, 0)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
timer = QTimer()
timer.timeout.connect(lambda: app.quit())
timer.start(100)
sys.exit( app.exec_() )
这里的问题是我们还没有设置任何 Python 事件。所以我们的事件循环永远不会搅动 Python 解释器,因此我们传递给 Python 进程的信号永远不会被处理。因此,在我们点击 Qt 应用程序窗口的退出按钮之前,我们的 Python 进程永远不会看到该信号。 (来源:https://machinekoder.com/how-to-not-shoot-yourself-in-the-foot-using-python-qt/)
【讨论】:
抱歉,您的代码没有多大意义(也没有您对原始问题的编辑)。 QTimer 不关心 HelloWindow 中会发生什么:您说它应该“移动一些粒子”,但不清楚这些粒子是如何移动的(它们是否使用一些定时事件移动?是否应该对移动进行处理)帧”一次?)以及该运动应该花费多少时间。如果您想显示某种动画并在动画结束后立即关闭窗口,您应该查找Animation Framework。 @musicamante 好吧,这就是我说我寻求通用解决方案时的真正意思。因此,首先我没有描述循环或函数/应用程序应该做的任何事情。我不希望 QTimer 关心我的程序,我希望它在我完成后立即关闭(这个解决方案似乎可以做到)。无论如何,它对我有用。感谢您的贡献,很抱歉打扰您。 没有“通用解决方案”,因为这完全取决于这些类的作用。在您的情况下,它可能有效,因为单次计时器“尽快”超时(这意味着它“留给所有班级的时间,至少完成他们的__init__
),但我不建议你这样做种方法。不幸的是,鉴于您的示例(开头太“抽象”),很难正确地帮助您:虽然,现在,它似乎有效,但恐怕您在取得一些进展时可能会遇到一些问题在您的程序开发中。以上是关于PyQt5 无需点击任何按钮或点击任何内容即可终止应用程序的主要内容,如果未能解决你的问题,请参考以下文章
无需在 Android Studio 中打开浏览器即可点击 URL