PyQt+Telethon实现按钮点击发Telegram消息报错求助
问题分析与解决
错误原因
- QThread的run方法不能定义为async协程:QThread的
start()方法会直接调用run(),但它不会处理协程对象,导致协程从未被await,触发RuntimeWarning。 - 类名拼写错误:定义的类是
SendMassage,但实例化时用了SendMessage,会引发名称错误。 - 全局客户端的线程安全问题:Telethon客户端在全局初始化,跨线程使用可能引发内存/线程异常,导致进程崩溃(退出码
0xC0000409通常与此类问题相关)。
修正后的代码
from PyQt6.QtWidgets import * from telethon import TelegramClient from PyQt6.QtCore import QThread import asyncio api_id = 'your_api_id' api_hash = 'your_api_hash' proxy = ("http", '192.xxx.xxx.xxx', 8xxx) # 替换为你的代理信息 class SendMessage(QThread): def __init__(self, parent=None): super().__init__(parent) def run(self): # 在子线程内创建客户端,避免跨线程资源冲突 client = TelegramClient('anon', api_id, api_hash, proxy=proxy) # 用asyncio.run执行异步任务流程 asyncio.run(self._send_message(client)) async def _send_message(self, client): await client.start() await client.send_message('me', 'hello') await client.disconnect() class SendMessageTest(QDialog): def __init__(self, parent=None): super().__init__(parent) self.PushButton = QPushButton("Send") self.setGeometry(300, 300, 300, 150) vbox = QVBoxLayout() vbox.addWidget(self.PushButton) self.setLayout(vbox) self.PushButton.clicked.connect(self.launch_send) self.sendMessage_instance = SendMessage() def launch_send(self): # 避免重复启动同一线程 if not self.sendMessage_instance.isRunning(): self.sendMessage_instance.start() import sys app = QApplication(sys.argv) main = SendMessageTest() main.show() sys.exit(app.exec())
关键修改点
- 调整异步方法结构:QThread的
run()改为普通方法,内部通过asyncio.run()执行独立的异步任务函数_send_message,解决协程未被await的问题。 - 子线程内初始化客户端:Telethon客户端在子线程中创建,确保线程安全,避免跨线程共享资源引发的崩溃。
- 修正类名拼写:统一类名为
SendMessage,消除实例化时的名称错误。 - 增加线程运行检查:点击按钮前判断线程状态,防止重复启动线程引发异常。
- 规范异步调用:
client.start()、send_message、disconnect()均使用await调用,保证异步流程完整执行。
内容的提问来源于stack exchange,提问作者Simon70
相关产品推荐
相关产品推荐

