python – 在不冻结GUI的情况下一起使用asyncio和Tkinter(或其他GUI库)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 在不冻结GUI的情况下一起使用asyncio和Tkinter(或其他GUI库),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3164字,纯文字阅读大概需要5分钟。
内容图文
![python – 在不冻结GUI的情况下一起使用asyncio和Tkinter(或其他GUI库)](/upload/InfoBanner/zyjiaocheng/705/6cb0ed4608104a6db85945065068f4d9.jpg)
我想将asyncio与tkinter GUI结合使用.
我是asyncio的新手,我对它的理解不是很详细.
单击第一个按钮时,此示例启动10个任务.任务只是使用sleep()模拟工作几秒钟.
Python 3.6.4rc1的示例代码运行良好.但
问题是GUI被冻结了.当我按下第一个按钮并启动10个asyncio任务时,我无法按下GUI中的第二个按钮,直到完成所有任务. GUI永远不应该冻结 – 这是我的目标.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from tkinter import *
from tkinter import messagebox
import asyncio
import random
def do_freezed():
""" Button-Event-Handler to see if a button on GUI works. """
messagebox.showinfo(message='Tkinter is reacting.')
def do_tasks():
""" Button-Event-Handler starting the asyncio part. """
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(do_urls())
finally:
loop.close()
async def one_url(url):
""" One task. """
sec = random.randint(1, 15)
await asyncio.sleep(sec)
return 'url: {}\tsec: {}'.format(url, sec)
async def do_urls():
""" Creating and starting 10 tasks. """
tasks = [
one_url(url)
for url in range(10)
]
completed, pending = await asyncio.wait(tasks)
results = [task.result() for task in completed]
print('\n'.join(results))
if __name__ == '__main__':
root = Tk()
buttonT = Button(master=root, text='Asyncio Tasks', command=do_tasks)
buttonT.pack()
buttonX = Button(master=root, text='Freezed???', command=do_freezed)
buttonX.pack()
root.mainloop()
一个_side问题
…是因为这个错误我无法再次运行任务.
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 1699, in __call__
return self.func(*args)
File "./tk_simple.py", line 17, in do_tasks
loop.run_until_complete(do_urls())
File "/usr/lib/python3.6/asyncio/base_events.py", line 443, in run_until_complete
self._check_closed()
File "/usr/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
多线程
多线程是一种可能的解决方案吗?只有两个线程 – 每个循环都有它自己的线程?
编辑:在回顾这个问题和答案后,它几乎与所有GUI库(例如PygObject / Gtk,wxWidgets,Qt,…)相关.
解决方法:
在稍微修改代码时,我在主线程中创建了asyncio event_loop,并将其作为参数传递给asyncio线程.现在Tkinter在获取网址时不会冻结.
from tkinter import *
from tkinter import messagebox
import asyncio
import threading
import random
def _asyncio_thread(async_loop):
async_loop.run_until_complete(do_urls())
def do_tasks(async_loop):
""" Button-Event-Handler starting the asyncio part. """
threading.Thread(target=_asyncio_thread, args=(async_loop,)).start()
async def one_url(url):
""" One task. """
sec = random.randint(1, 8)
await asyncio.sleep(sec)
return 'url: {}\tsec: {}'.format(url, sec)
async def do_urls():
""" Creating and starting 10 tasks. """
tasks = [one_url(url) for url in range(10)]
completed, pending = await asyncio.wait(tasks)
results = [task.result() for task in completed]
print('\n'.join(results))
def do_freezed():
messagebox.showinfo(message='Tkinter is reacting.')
def main(async_loop):
root = Tk()
Button(master=root, text='Asyncio Tasks', command= lambda:do_tasks(async_loop)).pack()
buttonX = Button(master=root, text='Freezed???', command=do_freezed).pack()
root.mainloop()
if __name__ == '__main__':
async_loop = asyncio.get_event_loop()
main(async_loop)
内容总结
以上是互联网集市为您收集整理的python – 在不冻结GUI的情况下一起使用asyncio和Tkinter(或其他GUI库)全部内容,希望文章能够帮你解决python – 在不冻结GUI的情况下一起使用asyncio和Tkinter(或其他GUI库)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。