我正在尝试自动化GUI后面的任务。我的GUI有多个按钮,这些按钮应该启动特定的函数,并且有一个按钮可以停止当前正在运行的任何函数。当一个函数正在运行时,除“取消”按钮外的所有按钮都会变灰。我需要额外的线程,以便在漫长的功能运行时,我的GUI仍然能够响应。
现在,我想实现一个装饰器来装饰这些函数。此装饰器应在单独的线程中运行函数。当用户按下取消按钮时,此额外线程中的函数应接收某种停止信号,装饰函数可以使用该信号停止其当前任务并退出。
我知道可以为每个函数实现类型为threading.Thread的类,并将当前函数插入为“def run(self):”,但这似乎不是一种优雅的解决方案。
有办法吗?对我来说,这似乎是一个常见的问题,但我没有通过Google找到任何解决方案,除了编写函数作为类并将其作为单独的线程运行。
但是,如果我创建类,它将会是这样的:
第二段代码要求为每个按钮编写一个类和函数,代码量更大,看起来更加复杂,我希望这并非必需。我是否理解错误或者做错了什么?
编辑2:
在salomonderossi的优秀示例之后,我的新代码:
现在,我想实现一个装饰器来装饰这些函数。此装饰器应在单独的线程中运行函数。当用户按下取消按钮时,此额外线程中的函数应接收某种停止信号,装饰函数可以使用该信号停止其当前任务并退出。
我知道可以为每个函数实现类型为threading.Thread的类,并将当前函数插入为“def run(self):”,但这似乎不是一种优雅的解决方案。
有办法吗?对我来说,这似乎是一个常见的问题,但我没有通过Google找到任何解决方案,除了编写函数作为类并将其作为单独的线程运行。
def function1:
function_code
但是,如果我创建类,它将会是这样的:
class class1(threading.Thread):
stopper = None
def __init__(self):
init_code
def run(self):
function_code
def function1:
t = class1()
t.stopper = some_stop_condition
t.run()
第二段代码要求为每个按钮编写一个类和函数,代码量更大,看起来更加复杂,我希望这并非必需。我是否理解错误或者做错了什么?
编辑2:
在salomonderossi的优秀示例之后,我的新代码:
def run_async(func):
@functools.wraps(func)
def async_func(*args, **kwargs):
queue = Queue.Queue()
t = threading.Thread(target=func, args=(queue,) + args, kwargs=kwargs)
t.start()
return queue, t
return async_func
# @layout_decorators.runInSeparateThread()
@run_async
def test2(myQueue):
print "executing test2"
import time
for k in range(6):
print k
try:
myQueue.get(False)
except Queue.Empty:
print "cancelled"
return
time.sleep(1)
def test22():
print "executing test22"
global globalQueue
globalQueue, t = test2()
if __name__ == "__main__":
import time
print "\n\n"
test22()
time.sleep(2)
globalQueue.put("stop")
但它在第一次机会就停止了线程。即使我删除了最后一行代码(我认为是停止线程的),我的输出结果仍然是:
executing test22
executing test2
0
cancelled
threading.Thread
类不是一个优雅的解决方案? - qvpham