Python Discord Bot多按钮实现求助:语法错误与ButtonStyle识别失败
问题解决步骤
1. 修复ButtonStyle识别问题
你的导入语句是正确的,但代码里写错了标识符:
- 错误写法:
discord.Buttonstyle(最后一个字母是小写s) - 正确写法:直接用
ButtonStyle(已经从discord.ui导入,无需加discord前缀),或者discord.ButtonStyle(注意大写S)
2. 修正核心语法与逻辑错误
你的代码存在大量基础语法和逻辑问题,关键错误点如下:
- 错误定义Button类:
class Button(*7, ...)完全不符合Python类定义语法,我们需要创建Button实例而非重定义类,且每个按钮的label、custom_id等属性要单独设置,不能把多个值堆在一起。 - 字符串语法错误:
label="strength" "agility"这种写法无效,Python不会自动拼接这类字符串,每个按钮需单独指定label。 - 逻辑结构混乱:在while循环里定义函数、直接
break跳出循环,完全无法实现按钮交互;CHSHT字典未初始化,会直接触发运行时错误。
3. 重构角色创建按钮功能
下面是重构后的完整可运行示例,实现属性分配(AP)和技能选择(SP)的按钮交互逻辑:
import discord from discord.ext import commands from discord.ui import ButtonStyle, Button, View # 初始化Bot实例(替换前缀和你的Token) Kanna = commands.Bot(command_prefix="!", intents=discord.Intents.all()) # 初始化角色属性字典 def init_character_sheet(): return { "str": 0, "agt": 0, "con": 0, "int": 0, "will": 0, "cha": 0, "luck": 0, "AP": 3, # 属性点数 "SP": 2 # 技能点数 } @Kanna.command() async def Adventure_time(ctx): CHSHT = init_character_sheet() # ---------------------- 属性分配阶段 ---------------------- class AttributeView(View): def __init__(self, char_sheet): super().__init__(timeout=60) # 60秒超时自动关闭交互 self.char_sheet = char_sheet # 通用属性点击回调 async def on_attr_click(self, interaction, attr_key): if self.char_sheet["AP"] <= 0: await interaction.response.send_message("属性点数已用完!", ephemeral=True) return self.char_sheet[attr_key] += 1 self.char_sheet["AP"] -= 1 # 更新消息显示当前状态 status_text = f"属性分配状态:\n" for key, val in self.char_sheet.items(): if key not in ["AP", "SP"]: status_text += f"{key.upper()}: {val} " status_text += f"\n剩余属性点数:{self.char_sheet['AP']}" await interaction.response.edit_message(content=status_text, view=self) # 创建属性按钮并添加到视图 attr_view = AttributeView(CHSHT) attr_list = [ ("Strength", "str", ButtonStyle.green), ("Agility", "agt", ButtonStyle.green), ("Constitution", "con", ButtonStyle.green), ("Intelligence", "int", ButtonStyle.green), ("Will", "will", ButtonStyle.green), ("Charisma", "cha", ButtonStyle.green), ("Luck", "luck", ButtonStyle.green) ] for label, key, style in attr_list: btn = Button(label=label, style=style, custom_id=key) btn.callback = lambda inter, k=key: attr_view.on_attr_click(inter, k) attr_view.add_item(btn) # 发送属性分配消息 await ctx.send(f"开始分配属性!剩余点数:{CHSHT['AP']}", view=attr_view) # ---------------------- 技能选择阶段 ---------------------- class SkillView(View): def __init__(self, char_sheet): super().__init__(timeout=60) self.char_sheet = char_sheet # 通用技能点击回调 async def on_skill_click(self, interaction, skill_key): if self.char_sheet["SP"] <= 0: await interaction.response.send_message("技能点数已用完!", ephemeral=True) return self.char_sheet[skill_key] = self.char_sheet.get(skill_key, 0) + 1 self.char_sheet["SP"] -= 1 # 更新消息显示当前状态 status_text = f"技能选择状态:\n" skill_map = { "mle": "Melee", "rgd": "Ranged", "cft": "Craft", "spl": "Spell", "bls": "Blessing", "prf": "Perform", "srv": "Survival" } for key, name in skill_map.items(): status_text += f"{name}: {self.char_sheet.get(key, 0)} " status_text += f"\n剩余技能点数:{self.char_sheet['SP']}" await interaction.response.edit_message(content=status_text, view=self) # 创建技能按钮并添加到视图 skill_view = SkillView(CHSHT) skill_list = [ ("Melee", "mle", ButtonStyle.primary), ("Ranged", "rgd", ButtonStyle.primary), ("Craft", "cft", ButtonStyle.primary), ("Spell", "spl", ButtonStyle.primary), ("Blessing", "bls", ButtonStyle.primary), ("Perform", "prf", ButtonStyle.primary), ("Survival", "srv", ButtonStyle.primary) ] for label, key, style in skill_list: btn = Button(label=label, style=style, custom_id=key) btn.callback = lambda inter, k=key: skill_view.on_skill_click(inter, k) skill_view.add_item(btn) # 发送技能选择消息 await ctx.send(f"开始选择技能!剩余点数:{CHSHT['SP']}", view=skill_view) # 启动Bot(替换成你的Bot Token) Kanna.run("YOUR_BOT_TOKEN_HERE")
关键说明
- 使用
discord.ui.View管理按钮是discord.py实现交互的标准方式,能自动处理按钮的生命周期和回调绑定。 - 每个按钮单独创建,通过lambda传递对应属性/技能的键值,避免回调逻辑重复。
- 初始化了角色属性字典,解决未定义变量的问题。
- 修复了
ButtonStyle的拼写错误,直接使用导入的标识符。
内容的提问来源于stack exchange,提问作者wizard
相关产品推荐
相关产品推荐

