You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时运行Tkinter与Pyrogram?解决长进程致界面卡顿问题

解决方案:线程分离耗时操作+可中断标志

问题根源

Tkinter是单线程UI框架,所有UI事件处理和更新都依赖主循环运行。你的代码中_handle_chat_history里的循环+time.sleep(1)会直接阻塞主循环,导致界面完全失去响应,无法处理Disconnect按钮的点击事件。

关键修改方案

  1. 线程分离耗时操作:将Pyrogram的循环发送逻辑放到子线程中,让主循环专注处理UI交互
  2. 添加可中断标志:用全局变量控制子线程的循环是否提前退出,实现点击Disconnect立即停止的效果
  3. UI操作限制在主线程:所有修改Tkinter控件的操作必须在主线程执行,避免跨线程操作引发异常
  4. 线程生命周期管理:使用守护线程确保程序退出时线程自动终止,断开连接时同步终止子线程

修改后的完整代码

import tkinter as tk
from pyrogram import Client
from pyrogram.errors import ApiIdInvalid, UsernameNotOccupied
import time
import threading
import os

app = Client(os.getcwd() + "\\users\\main")
stop_flag = False
chat_thread = None

def toggle_connection():
    global stop_flag, chat_thread
    if not app.is_connected:
        try:
            app.start()
            print("Pyrogram bağlandı!")
            # 重置停止标志并启动子线程执行发送任务
            stop_flag = False
            chat_thread = threading.Thread(target=_handle_chat_history, daemon=True)
            chat_thread.start()
            # 主线程更新按钮文本
            connect_button.config(text="Disconnect")
        except ApiIdInvalid:
            print("API ID veya API Hash yanlış!")
        except UsernameNotOccupied:
            print("Kullanıcı adı mevcut değil!")
    else:
        _handle_disconnect()

def _handle_chat_history():
    global stop_flag
    for _ in range(10):
        if stop_flag:
            break  # 检测到停止信号,立即退出循环
        try:
            app.send_message("me", "a")
        except Exception as e:
            print(f"Mesaj gönderilirken hata: {e}")
            break
        time.sleep(1)
    # 任务正常结束后自动断开连接
    if not stop_flag:
        root.after(0, _handle_disconnect)

def _handle_disconnect():
    global stop_flag, chat_thread
    stop_flag = True
    # 等待子线程终止(超时1秒避免阻塞)
    if chat_thread and chat_thread.is_alive():
        chat_thread.join(timeout=1)
    app.stop()
    print("Pyrogram bağlantısı kesildi!")
    connect_button.config(text="Connect")

root = tk.Tk()
root.title("Pyrogram Connector")

connect_button = tk.Button(root, text="Connect", command=toggle_connection)
connect_button.pack(pady=20)

def _on_closing():
    _handle_disconnect()
    root.destroy()

root.protocol("WM_DELETE_WINDOW", _on_closing)
root.mainloop()

代码说明

  • toggle_connection:启动Pyrogram连接后,创建守护线程执行发送任务,立即更新按钮状态,保证界面不卡顿
  • _handle_chat_history:每次循环前检查停止标志,收到停止信号就立即退出;任务正常完成后自动触发断开逻辑
  • _handle_disconnect:设置停止标志终止子线程,停止Pyrogram客户端,最后更新按钮文本
  • _on_closing:窗口关闭时先执行断开操作,避免程序残留连接

内容的提问来源于stack exchange,提问作者aev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:40:31