使用Tkinter轻松实现多线程
tkthread的Python项目详细描述
tkthread
在cpython 2.7/3.x和pypy 2.7/3.x上使用tkinter轻松实现多线程。
背景
python附带的tcl/tk语言遵循不同的线程 Python本身的模型,它可以在混合Python时引起钝化错误。 带有tkinter的线程,例如:
RuntimeError: main thread is not in main loop
RuntimeError: Calling Tcl from different apartment
NotImplementedError: Call from another thread
tcl可以有许多独立的解释器,每个解释器都被标记到 创建时它的特定操作系统线程。python的tkinter模块检查 如果调用的python线程与tcl/tk线程不同,如果是, waits one second开始tcl/tk主循环 派遣。如果超时,则会引发运行时错误。在Pypy身上, 出现NotImplementedError。
对于tcl中的非tk调用,python将引发单元运行时错误 从其他线程调用tcl解释器时。
避免这些错误的一种常见方法是使用.after
设置
^来自message queue的{a3}
tcl/tk主循环,这会降低gui的响应速度。
在tkthread
中使用的方法是使用tcl/tk thread::send
通知tcl/tk主循环执行调用的消息传递。
这种中断式架构具有更低的延迟和更好的
CPU利用率高于定期轮询。
用法
tkthread
模块提供了TkThread
类,它可以
与主线程同步交互。
from tkthread import tk, TkThread
root = tk.Tk() # create the root window
tkt = TkThread(root) # make the thread-safe callable
import threading, time
def run(func):
threading.Thread(target=func).start()
run(lambda: root.wm_title('FAILURE'))
run(lambda: tkt(root.wm_title,'SUCCESS'))
root.update()
time.sleep(2) # _tkinter.c:WaitForMainloop fails
root.mainloop()
tkt
实例是可调用的,它将等待tcl/tk主循环
执行和计算一个结果,然后返回给
返回调用线程。非同步版本也存在。
不阻止:
tkt.nosync(root.wm_title, 'ALSO SUCCESS')
有一个可选的tkt.install()
方法可以将python截取到tk
电话。在创建子级之前,必须在默认根上调用此命令
小部件。如果已安装,则使用
tkt
不是必需的。但是,对于
Tkinter小部件只在主线程上运行,因为
间接线程检查。
tcl/tk解释器必须是 主线。如果不是,则会收到tclerror,格式如下:
_tkinter.TclError: invalid command name "140520536224520_call_from"
例如,创建几个Tk()
实例,然后使用tkthread
会导致这个错误。
一个好的实践是创建一个根窗口,然后调用root.withdraw()
使主tcl/tk解释器保持活动状态。未来顶层窗口
使用root
作为主控。
安装
pip install tkthread
许可证
根据apache许可证2.0版(以下简称“许可证”)授权
另请参见
这些库使用定期轮询提供类似的功能:
- https://github.com/RedFantom/mtTkinter
- https://github.com/abarnert/mttkinter
- https://pypi.org/project/threadsafe-tkinter