【问题标题】:Telethon async function to tkinter buttonTelethon 异步功能到 tkinter 按钮
【发布时间】:2020-09-19 07:52:18
【问题描述】:

我在下面有这个异步功能,基本上我想使用 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()

【问题讨论】:

    标签: python bots telegram telethon


    【解决方案1】:

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

    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-friendly tkinter 应用,请参阅Telethon's gui.py example

    【讨论】:

    • 我试图理解并实施您的解决方案,但由于我是编程新手,所以我无法做到。我还进入了你的 Git Hub,测试了你的 GUI,太棒了!!它看起来像我想要实现的,但更好!我试图阅读代码并理解,但我很迷茫;对于我必须阅读和学习的内容,您是否有任何提示或文档?
    • 我会说 GUI 不是一个容易学习编程的主题,至少在我的观点和我所知道的语言中不是。我建议先学习 Python 编程,然后再尝试处理 GUI。
    猜你喜欢
    • 1970-01-01
    • 2019-03-22
    • 2022-11-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多