以下代码按照预期工作:
- 有一个名为"Ernie"的QThread,从1数到8,在计数之间休眠1秒。 - 有一个无意义的UI部件("Bert")。 - 在正常操作下,程序运行直到线程完成并关闭UI。 - Ctrl-C键盘中断将在正常完成之前优雅地停止程序。
为了实现这一点,我必须将1秒的休眠时间分成50毫秒的块,并检查一个标志。 有没有更Pythonic的方法在线程中睡眠一段时间(例如1秒),但可以通过某个标志或信号进行中断?
我宁愿这样做,并在线程中某种方式引发GracefulShutdown异常:
完整程序;
- 有一个名为"Ernie"的QThread,从1数到8,在计数之间休眠1秒。 - 有一个无意义的UI部件("Bert")。 - 在正常操作下,程序运行直到线程完成并关闭UI。 - Ctrl-C键盘中断将在正常完成之前优雅地停止程序。
为了实现这一点,我必须将1秒的休眠时间分成50毫秒的块,并检查一个标志。 有没有更Pythonic的方法在线程中睡眠一段时间(例如1秒),但可以通过某个标志或信号进行中断?
try:
for i in xrange(8):
print "i=%d" % i
for _ in xrange(20):
time.sleep(0.05)
if not self.running:
raise GracefulShutdown
except GracefulShutdown:
print "ernie exiting"
我宁愿这样做,并在线程中某种方式引发GracefulShutdown异常:
try:
for i in xrange(8):
print "i=%d" % i
time.sleep(1)
# somehow allow another thread to raise GracefulShutdown
# during the sleep() call
except GracefulShutdown:
print "ernie exiting"
完整程序;
from PySide import QtCore, QtGui
from PySide.QtGui import QApplication
import sys
import signal
import time
class GracefulShutdown(Exception):
pass
class Ernie(QtCore.QThread):
def __init__(self):
super(Ernie, self).__init__()
self.running = True
def run(self):
try:
for i in xrange(8):
print "i=%d" % i
for _ in xrange(20):
time.sleep(0.05)
if not self.running:
raise GracefulShutdown
except GracefulShutdown:
print "ernie exiting"
def shutdown(self):
print "ernie received request to shutdown"
self.running = False
class Bert(object):
def __init__(self, argv):
self.app = QApplication(argv)
self.app.quitOnLastWindowClosed = False
def show(self):
widg = QtGui.QWidget()
widg.resize(250, 150)
widg.setWindowTitle('Simple')
widg.show()
self.widg = widg
return widg
def shutdown(self):
print "bert exiting"
self.widg.close()
def start(self):
# return control to the Python interpreter briefly every 100 msec
timer = QtCore.QTimer()
timer.start(100)
timer.timeout.connect(lambda: None)
return self.app.exec_()
def handleInterrupts(*actors):
def handler(sig, frame):
print "caught interrupt"
for actor in actors:
actor.shutdown()
signal.signal(signal.SIGINT, handler)
bert = Bert(sys.argv)
gratuitousWidget = bert.show()
ernie = Ernie()
ernie.start()
handleInterrupts(bert, ernie)
retval = bert.start()
print "bert finished"
while not ernie.wait(100):
# return control to the Python interpreter briefly every 100 msec
pass
print "ernie finished"
sys.exit(retval)