首页 > 解决方案 > Telethon 异步功能到 tkinter 按钮

问题描述

我在下面有这个异步功能,基本上我想使用 tkinter 将它放入按钮的命令中。

async def main():
    await client.send_message('username', 'message')

with client:
    client.loop.run_until_complete(main())

message我想把cpf我的代码的变量,但我不知道应该如何把它放在一起。我对python很陌生,很抱歉有什么不对...

上面的代码是我尝试执行的操作,但它只是在我运行代码时运行该函数,而不是在我按下Button. 我越来越ValueError: The message cannot be empty unless a file is provided

from telethon import TelegramClient, events, sync
from tkinter import *

api_id = xxxxx
api_hash = 'xxxxxx'

client = TelegramClient('session_name', api_id, api_hash)
client.start()

root = Tk()

canvas = Canvas(root)
canvas.pack()

code_entry = Entry(canvas)
code_entry.pack()

async def main():
    cpf = code_entry.get()
    await client.send_message('ConsignadoBot', cpf)

with client:
    client.loop.run_until_complete(main)

search_btn = Button(canvas, text='Consultar', command=main)
search_btn.pack()

root.mainloop()

标签: pythonbotstelegramtelethon

解决方案


在产生您声称拥有的错误之前,您的代码会产生完全不同的错误。

with client:
    client.loop.run_until_complete(main)

此行失败,因为在 中loop.run_until_complete(),“需要一个asyncio.Future、一个协程或一个等待”:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 558, in run_until_complete
    future = tasks.ensure_future(future, loop=self)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 619, in ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required

正确的代码是:

with client:
    client.loop.run_until_complete(main())

现在,它会出现“空消息”错误,因为它在用户输入任何内容之前执行。


这段代码:

root.mainloop()

正在阻塞。Telethon 是一个asyncio库,这意味着除非您执行其他操作,否则事件循环不会运行,这意味着 Telethon 将无法取得任何进展。

这可以通过使其异步来解决:

async def main(interval=0.05):
    try:
        while True:
            # We want to update the application but get back
            # to asyncio's event loop. For this we sleep a
            # short time so the event loop can run.
            #
            # https://www.reddit.com/r/Python/comments/33ecpl
            root.update()
            await asyncio.sleep(interval)
    except KeyboardInterrupt:
        pass
    except tkinter.TclError as e:
        if 'application has been destroyed' not in e.args[0]:
            raise
    finally:
        await client.disconnect()

client.loop.run_until_complete(main())

有关更精心设计的async友好 tkinter 应用程序,请参阅Telethon 的gui.py示例


推荐阅读