2

我一起使用 Tkinter 和 discord.py,我希望它在按下按钮时更改用户的昵称。要更改昵称,discord.py 使用该命令yield from client.change_nickname(server.me, string) ,但是当我在按钮命令中运行该代码时,该函数永远不会运行。我使用了一个打印语句来确保,并且没有一个函数被运行。我尝试使用多线程启动该功能,但没有奏效,任何帮助将不胜感激

async def test2():
    server = client.get_server("345548250432012298")
    await client.change_nickname(server.me, "testing")
def test():
    threading.Thread(target=test2).start()
def makeThing(nicks):
    frame = Tk()
    for i in range(0, len(nicks)):
        Button(frame, text=nicks[i], command= test).grid(row=i)
    frame.mainloop()
4

1 回答 1

0

您的问题是您正在尝试async def使用该threading模块调用协程。为了使这项工作,您需要使用asyncio在您的test函数中运行一个事件循环。假设您不关心主线程中长时间运行的调用的影响,您可以直接使用run_until_complete.

import asyncio

async def test2():
    server = client.get_server("345548250432012298")
    await client.change_nickname(server.me, "testing")
def test():
    loop = asyncio.get_event_loop()  
    loop.run_until_complete(test2())
    loop.close()  
def makeThing(nicks):
    frame = Tk()
    for i in range(0, len(nicks)):
        Button(frame, text=nicks[i], command= test).grid(row=i)
    frame.mainloop()

如果您需要在一个事件循环中进行更多异步调用,请ensure_future改用。threading请注意,只要您在线程中调用,就可以使用(如您正确推测的那样)将异步调用中断到它自己run_until_complete的线程中。

这个答案应该可以帮助您使用带有 asyncio 的线程(在那个答案中,@asyncio.coroutine通常等同于async def 但确实存在一些差异),并且这个async/await 教程应该可以很好地为您提供一般学习。

于 2017-10-04T05:00:20.970 回答