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

无需点击来自 AppWidgetProvider 的任何事件即可开始另一个活动

PYQT5中如何将按钮点击连接的结果输出到界面上

检测点击触摸屏的两个按钮

将数据从片段发送到活动,无需任何事件处理或侦听器

是否有任何可能的方法来触发工具提示而无需任何点击功能?