如何从Discord.py按钮组件获取用户交互响应数据
你的代码存在两个核心问题导致无法获取按钮响应:
await context.send()返回的是Message对象,并非用户点击按钮后的返回值,因此user_response永远不会等于1或<。- 按钮回调函数里的
return无法被外部捕获,因为这些回调是Discord.py内部触发的异步函数,和你的调用代码不属于同一执行流。
以下是两种可行的解决方案:
方案一:通过View类属性存储交互结果
修改SelectionButtons类,添加属性存储用户选择,在按钮回调中完成交互回应并终止View,最后读取结果:
# 修改后的SelectionButtons类 import discord class SelectionButtons(discord.ui.View): def __init__(self, *, timeout=60): super().__init__(timeout=timeout) # 初始化存储用户选择的属性 self.user_choice = None @discord.ui.button(label='1', style=discord.ButtonStyle.blurple) async def button1(self, button: discord.ui.Button, interaction: discord.Interaction): # 回应Discord交互请求,避免按钮持续加载 await interaction.response.send_message("你选择了1", ephemeral=True) # 记录用户选择 self.user_choice = 1 # 终止View,结束等待 self.stop() @discord.ui.button(label='<', style=discord.ButtonStyle.red) async def buttonback(self, button: discord.ui.Button, interaction: discord.Interaction): await interaction.response.send_message("你选择了返回", ephemeral=True) self.user_choice = '<' self.stop()
调用代码修改为:
view = SelectionButtons() await context.send(embed=embed, view=view) # 等待用户点击按钮或超时 await view.wait() # 读取并处理用户选择 if view.user_choice == 1: print('1') elif view.user_choice == '<': print('<') else: print("用户未在规定时间内点击按钮")
方案二:直接在按钮回调中处理逻辑
如果无需将结果传回调用代码,可直接在回调函数内执行业务逻辑:
# 修改后的SelectionButtons类 import discord class SelectionButtons(discord.ui.View): def __init__(self, *, timeout=60): super().__init__(timeout=timeout) @discord.ui.button(label='1', style=discord.ButtonStyle.blurple) async def button1(self, button: discord.ui.Button, interaction: discord.Interaction): await interaction.response.send_message("你选择了1", ephemeral=True) # 直接处理选择1后的逻辑 print('1') # 可选:终止View使按钮失效 self.stop() @discord.ui.button(label='<', style=discord.ButtonStyle.red) async def buttonback(self, button: discord.ui.Button, interaction: discord.Interaction): await interaction.response.send_message("你选择了返回", ephemeral=True) print('<') self.stop()
调用代码简化为:
view = SelectionButtons() await context.send(embed=embed, view=view)
关键注意事项
- 所有按钮回调必须调用
interaction.response相关方法(如send_message、defer),否则Discord会判定交互失败,按钮会一直显示加载状态。 ephemeral=True会让回应仅对点击按钮的用户可见,适合私密操作,不需要可移除该参数。self.stop()会终止View,使所有按钮失效,若需允许用户多次点击,可省略该调用。
内容的提问来源于stack exchange,提问作者Kim
相关产品推荐
相关产品推荐

