【问题标题】:How to deal with two event loops? Pyrogram's and Tkinter's如何处理两个事件循环? Pyrogram 和 Tkinter 的
【发布时间】:2022-01-07 15:20:10
【问题描述】:

我正在使用 Pyrogram 和 Tkinter:

from tkinter import *
from pyrogram import Client

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

首先,我用 Pyrogram 注册一个处理程序:

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

其次,我向 Tkinter 注册了一个处理程序:

def button(event):
    print("Button!")
    
root.bind('<Button>', button)

但是如何启动 Pyrogram 和 Tkinter 的循环呢? 显然以下(或相反)不起作用:

root.mainloop()
app.run()

编辑: 由于 Pyrogram 的关键特性之一是它是完全异步的(例如,https://docs.pyrogram.org/start/updates#registering-a-handler),我希望得到基于 Asyncio 的答案。然而,这是我尝试通过@SylvesterKruin 对 cme​​ts 进行线程化。

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

Il 以 RuntimeError: There is no current event loop in thread 'Thread-1' 失败。

【问题讨论】:

  • 我不知道 Pyrogram,但会使用线程工作吗?您可以在主线程中使用tkinter 代码,在另一个线程中使用pyrogram 代码。
  • @SylvesterKruin 我已经编辑了我的问题并尝试线程化。
  • @SylvesterKruin 我已经进行了相应的编辑。但它仍然失败。
  • 正如@SylvesterKruin 首先所说的,你应该使用线程来分割pyrogramtkinter 这会让事情变得更干净,即使有work arounds for asyncio and tkinter,你也需要同步无论如何,api 和 gui 框架。 Exampels for tkinter and threading 可用,一旦你有东西要展示,它确实有效,我建议将你的代码发布到 CodeReview 那里你可以获得额外的输入。
  • 即使我赞成你的问题,因为它看起来很有用并且有研究。它目前一次陈述多个问题,不适合Stack Overflow。所以我投票结束这个问题,但随时提出一个更关注特定错误或意外行为的后续问题。您可以在Software Engineering 或另一个sites by Stack Exchange 提出这个问题

标签: python tkinter telegram python-multithreading pyrogram


【解决方案1】:

查看pyrogram examplesThis answer 以防止阻塞。我认为这可能会有所帮助。

import asyncio
import tkinter as tk
from pyrogram import Client
import threading

api_id = 12345
api_hash = "0123456789abcdef0123456789abcdef"
app = Client("my_account", api_id, api_hash)

def init_async():
    print('starting')
    loop = asyncio.get_event_loop()  # create loop
    event = asyncio.Event()  # create event
    #new thread to run loop. Prevents tkinter from blocking
    thr = threading.Thread(target=run_main, args=(loop, event))
    thr.start()

def run_main(_loop, _e):
    try:
        _loop.run_until_complete(main())
    finally:
        _loop.close()


async def main():
    async with app:
        await app.send_message("me", "Greetings from **Pyrogram**!")

@app.on_message()
async def message(client, message):
    print("Message!")

def button(event):
    print("Button!")

root = tk.Tk()
root.bind('<Button>', button)
tk.Button(master=root, text='Start Pyrogram', command=init_async).pack()
root.mainloop()

【讨论】:

  • 我想在 Tkinter 注册的处理程序 button 怎么样?
  • 处理程序button包括
  • 它不起作用。当我收到消息时,不会调用处理程序message
  • 您最初的挑战是“我怎样才能启动 Pyrogram 和 Tkinter 的循环”,就是这样做的。您可能想为此提出一个新问题。
猜你喜欢
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多