Reputation: 13
I have the this async function below and basically I wanna place It into the command of a button using tkinter.
async def main():
await client.send_message('username', 'message')
with client:
client.loop.run_until_complete(main())
In message
I wanna put the variable cpf
of my code, but I don't know exactly how should place It all together. I'm very new with python, so sorry for anything wrong...
The code above is how I'm trying to do it, but It's running the function just when I run the code, and not when I press the Button
. I'm getting 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()
Upvotes: 1
Views: 1912
Reputation: 7096
Your code produces a completely different error before producing the one you claim to have.
with client:
client.loop.run_until_complete(main)
This line fails, because in loop.run_until_complete()
, "an asyncio.Future
, a coroutine or an awaitable is required":
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
The correct code would be:
with client:
client.loop.run_until_complete(main())
Now, it will error with "empty message" because it's executing before the user enters anything.
This code:
root.mainloop()
Is blocking. Telethon is an asyncio
library, which means the event loop won't be running unless you do something else, which means Telethon won't be able to make any progress.
This can be solved by making it async:
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())
For a more carefully designed async
-friendly tkinter app, see Telethon's gui.py
example.
Upvotes: 2