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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:45:29