考虑以下示例:
import asyncio
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.create_widgets()
self._configure_bindings() # I believe it is not possible
# to do this if the method needs
# to be async as well
def create_widgets(self):
pass
def _configure_bindings(self):
self.bind('<F5>', self.spam) # what's the proper way?
# does this method need to be async as well?
async def spam(self, event):
await self.do_something()
async def do_something():
pass
async def run_tk(root):
try:
while True:
root.update()
await asyncio.sleep(.01)
except tk.TclError as e:
if "application has been destroyed" not in e.args[0]:
raise
if __name__ == '__main__':
app = App()
asyncio.get_event_loop().run_until_complete(run_tk(app))
将异步方法绑定到tkinter中的键击的正确方法是什么? 我尝试过类似的事情:
self.bind('<F5>', self.spam)
self.bind('<F5>', await self.spam)
self.bind('<F5>', await self.spam())
self.bind('<F5>', lambda event: await self.spam(event))
......以及其他一些组合,但无济于事。
答案 0 :(得分:3)
after
方法和bindings, tkinter
本身是异步的。
但是,如果您仍然坚持使用asyncio
,那么首先考虑一下您的尝试。
您的第一次尝试显然是失败,因为当spam
为coroutine
时,您尝试将await coroutine
作为通用函数进行调用。您的其他尝试比第一次尝试更正确,但yield from coroutine
或import asyncio
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self._configure_bindings()
def _configure_bindings(self):
self.bind('<F5>', lambda event: asyncio.ensure_future(self.spam(event)))
async def spam(self, event):
await self.do_something()
await asyncio.sleep(2)
print('%s executed!' % self.spam.__name__)
async def do_something(self):
print('%s executed!' % self.do_something.__name__)
async def run_tk(root):
try:
while True:
root.update()
await asyncio.sleep(.01)
except tk.TclError as e:
if "application has been destroyed" not in e.args[0]:
raise
if __name__ == '__main__':
app = App()
asyncio.get_event_loop().run_until_complete(run_tk(app))
只能用于从另一个协程启动协程,因此它会再次失败。
因此,启动该野兽的正确方法是使用自解释方法ensure_future
(或旧的async
对其执行进行调度,这只是一个不赞成使用的别名)。
试试这个例子:
update
此外,我认为值得提及this问题,因为您使用了 try (Socket socket=new Socket(ipAddress, port);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())) {
//this is how you can use socket & out
out.write(null);
socket.getInetAddress();
}
方法。