如何使用线程自动关闭PyQt/PySide窗口?

2024-05-14 20:05:58 发布

您现在位置:Python中文网/ 问答频道 /正文

如何使PyQt5窗口在30秒后自动关闭,并且仍然保持窗口对交互的响应?在

我正在创建一个休眠30秒的线程,然后它调用窗口的close()函数。现在,代码挂在self.close()

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\fredrik\.conda\envs\pysidedev_py27\lib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "C:\Users\fredrik\.conda\envs\pysidedev_py27\lib\threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Users\fredrik\Desktop\timer.py", line 47, in <lambda>
    my_win.execute_function_threaded(func=lambda: my_win.auto_close(n=3))
  File "C:\Users\fredrik\Desktop\timer.py", line 36, in auto_close
    self.close()  # hangs
RuntimeError: Internal C++ object (MyWindow) already deleted.

我也尝试过将线程移出窗口对象,但仍然遇到挂起window.close()。在

我做错什么了?在

代码必须与python2.7和3.5一起使用。在

^{pr2}$

请注意,Qt绑定导入就是这样完成的,目的是使代码在您的端上运行更容易;)


Tags: 代码inpyselfcloselibline线程
2条回答

原始代码不能工作的原因是禁止从辅助线程调用qtgui方法(Qt方法不是线程安全的)。有几种解决方法,例如:

  • 使用QTimer(由于QTimer不使用线程,只在主线程中存在的Qt event循环中对将来的事件进行排队,此解决方案应该解决segfaults-请参阅@ingvar)的答案。

  • 使用QThread和自定义Qt信号。Qt信号是线程安全的,因此可以将辅助线程中的信号连接到主线程中的close插槽。然后,您可以在30秒后从次线程中发出信号来触发关闭。

你应该采取的方法取决于你的最终目标(以及这是一个多么“玩具”的例子),但目前我认为没有理由有第二个线程。你应该接受@ingvar的回答:)

不管怎样,在Qt中使用python线程都是个坏主意。坚持使用QThread,除非线程完全独立于GUI。在

请尝试以下代码,而不是my_win.execute_function_threaded调用:

class MyWindow(QtWidgets.QMainWindow):
    """Auto-closing window"""
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        QtCore.QTimer.singleShot(30000, self.close)

相关问题 更多 >

    热门问题