Python 如何使用线程自动关闭PyQt/PySide窗口?
如何使PyQt5窗口在30秒后自动关闭,并且仍然保持窗口对交互的响应 我正在创建一个休眠30秒的线程,然后它调用窗口的Python 如何使用线程自动关闭PyQt/PySide窗口?,python,pyqt4,pyside,pyqt5,pyside2,Python,Pyqt4,Pyside,Pyqt5,Pyside2,如何使PyQt5窗口在30秒后自动关闭,并且仍然保持窗口对交互的响应 我正在创建一个休眠30秒的线程,然后它调用窗口的close()函数。现在,代码挂起在self.close(): 请注意,Qt绑定导入就是这样做的,目的是让代码在您的终端上更容易运行;) 尝试以下代码而不是my\u win。执行函数线程化调用: class MyWindow(QtWidgets.QMainWindow): """Auto-closing window""" def __init__(self, p
close()
函数。现在,代码挂起在self.close()
:
请注意,Qt绑定导入就是这样做的,目的是让代码在您的终端上更容易运行;) 尝试以下代码而不是
my\u win。执行函数线程化调用:
class MyWindow(QtWidgets.QMainWindow):
"""Auto-closing window"""
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
QtCore.QTimer.singleShot(30000, self.close)
原始代码无法工作的原因是禁止从辅助线程调用QtGUI方法(Qt方法不是线程安全的)。有几种解决方案,例如:
- 使用
QTimer
(由于QTimer
不使用线程,而只是将主线程中存在的Qt事件循环中的未来事件排队,因此此解决方案应解决segfaults-请参阅的答案)
- 使用
QThread
和自定义Qt信号。Qt信号是线程安全的,因此您可以将次线程中的信号连接到主线程中的close
插槽。然后,您可以在30秒后从次线程内发出信号以触发关闭
你应该采取的方法取决于你的最终目标(以及这个“玩具”的例子有多大),但现在我看不出有任何理由有第二个线程。您只需使用@ingvar的答案:)
另外,无论哪种方式,在Qt中使用python线程都是一个坏主意。坚持使用QThread
,除非线程完全独立于GUI。我已经测试了代码,并且它没有阻止小部件,您可以评论说,PyQt的版本,PyQt的版本Python@eyllanesc不知道你是什么意思,无论我测试的是Python版本还是Qt绑定/版本,窗口都会在这里崩溃。例如,我尝试了Python 2.7/PySide、Python 3.5/PyQt5,其中窗口崩溃。
import sys
import time
from threading import Thread
try:
from PyQt5 import QtWidgets
except ImportError:
try:
from PySide2 import QtWidgets
except ImportError:
try:
from PyQt4 import QtGui as QtWidgets
except ImportError:
try:
from PySide import QtGui as QtWidgets
except ImportError:
print('giving up!')
class MyWindow(QtWidgets.QMainWindow):
"""Auto-closing window"""
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
def closeEvent(self, event):
"""Delete object when closed"""
self.deleteLater()
def auto_close(self, n):
"""Close self in n seconds"""
print('going to sleep')
for i in range(n):
print('sleeping...')
time.sleep(1)
print('done sleeping!')
self.close() # hangs
def execute_function_threaded(self, func):
"""Run given function in thread"""
self.t = Thread(target=func)
self.t.start()
print('thread started')
app = QtWidgets.QApplication(sys.argv)
my_win = MyWindow()
my_win.show()
my_win.execute_function_threaded(func=lambda: my_win.auto_close(n=3))
sys.exit(app.exec_())
class MyWindow(QtWidgets.QMainWindow):
"""Auto-closing window"""
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
QtCore.QTimer.singleShot(30000, self.close)