es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo lidiar con dos bucles de eventos: el de Pyrogram y el de Tkinter

Estoy utilizando Pyrogram y Tkinter:

from tkinter import *
from pyrogram import Client

root = Tk()
app = Client("my_account")

Primero, registro un controlador con Pyrogram:

@app.on_message()
def message(client, message):
    print("¡Mensaje!")

Segundo, registro un controlador con Tkinter:

def button(event):
    print("¡Botón!")

root.bind('<button>', button)

Pero, ¿cómo puedo iniciar los bucles para Pyrogram y Tkinter?
Obviamente, lo siguiente (o al revés) no funciona:

root.mainloop()
app.run()

Editar: Dado que una de las características clave de Pyrogram es que es completamente asíncrono (por ejemplo, https://docs.pyrogram.org/start/updates#registering-a-handler), esperaría una respuesta basada en Asyncio. Sin embargo, aquí está mi intento con threading siguiendo los comentarios de @SylvesterKruin.

t = Thread(target=app.run)
t.start()
root.mainloop()

Sin embargo, falla con RuntimeError: There is no current event loop in thread 'Thread-1'.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como Pyrogram y Tkinter utilizan bucles de eventos diferentes, no pueden ejecutarse juntos en el mismo hilo. Una posible solución es utilizar múltiples subprocesos. Puedes iniciar el bucle de eventos de Pyrogram en un subproceso separado y luego iniciar el bucle principal de Tkinter en el hilo principal. Aquí tienes un ejemplo:

    import threading
    from tkinter import *
    from pyrogram import Client
    
    root = Tk()
    app = Client("my_account")
    
    @app.on_message()
    def message(client, message):
        print("¡Mensaje!")
    
    def run_pyrogram():
        app.run()
    
    t = threading.Thread(target=run_pyrogram)
    t.start()
    
    root.mainloop()
    

    En este ejemplo, definimos una nueva función run_pyrogram() que inicia el bucle de eventos de Pyrogram utilizando app.run() en un subproceso separado. Luego, iniciamos este subproceso utilizando la clase threading.Thread.

    En el hilo principal, iniciamos el bucle principal de Tkinter utilizando root.mainloop(). Como resultado, tanto Pyrogram como Tkinter se ejecutarán simultáneamente pero en hilos diferentes.

    Ten en cuenta que este enfoque puede tener limitaciones debido al bloqueo global del intérprete (GIL). Si tu aplicación implica tareas limitadas por la CPU, es posible que necesites utilizar la multiprocesamiento en lugar de subprocesamiento. Alternativamente, puedes utilizar un marco asíncrono como Trio o AsyncIO para gestionar tanto los bucles de eventos de Pyrogram como de Tkinter en un solo hilo.

Comments are closed.