Discord UI Button交互失败:测试按钮功能异常求助
问题原因及修复方案
核心问题
你的代码存在两个关键问题导致交互失败:
- 事件处理冲突:同时使用
@bot.listen("button_click")监听器和bot.wait_for("button_click")等待事件,两者会争抢同一个交互事件,导致interaction.response被多次调用,触发Discord的交互响应限制(每个交互只能响应一次)。 - 重复注册监听器:每次执行
test命令都会在内部注册一个新的button_click监听器,后续按钮点击会触发多个监听器实例,进一步加剧响应冲突。
修复方案
方案1:使用View类绑定按钮回调(推荐)
这是Discord.py官方推荐的UI组件使用方式,逻辑更清晰且避免事件冲突:
import discord from discord.ext import commands @bot.command() async def test(ctx): # 定义带回调的View子类 class TestView(discord.ui.View): @discord.ui.button(label="test", custom_id="test") async def test_button_callback(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message("Test worked!") # 创建View实例并发送消息 view = TestView(timeout=15.0) message = await ctx.send("Click the button below to test!", view=view) # 等待View超时,超时后移除按钮 await view.wait() await message.edit(content="Timed out.", view=None)
方案2:仅使用wait_for(适合临时一次性交互)
如果坚持用wait_for,需要删除内部的@bot.listen监听器,避免冲突:
import discord from discord.ext import commands import asyncio @bot.command() async def test(ctx): view = discord.ui.View() view.add_item(discord.ui.Button(label="test", custom_id="test")) message = await ctx.send("Click the button below to test!", view=view) try: # 等待按钮点击事件 interaction = await bot.wait_for("button_click", check=lambda inter: inter.message.id == message.id, timeout=15.0) await interaction.response.send_message("Test worked!") except asyncio.TimeoutError: await message.edit(content="Timed out.", view=None) except Exception as e: await ctx.send(f"An error occurred: {e}")
额外注意事项
- 确保你的Discord.py版本是v2.x及以上,旧版本的UI组件API存在兼容性问题。
- 交互响应必须在3秒内完成,如果需要耗时操作,先调用
await interaction.response.defer(),后续再通过await interaction.followup.send()发送结果。
内容的提问来源于stack exchange,提问作者allencody_
相关产品推荐
相关产品推荐

