如何在discord.py中根据变量条件禁用Button组件?
你的代码无法运行的核心原因是:@ui.button装饰器在类定义阶段就会执行,此时类的实例还未创建,self根本不存在,因此不能直接在装饰器的disabled参数中使用self.a > self.b这类依赖实例变量的判断逻辑。
要实现根据实例变量动态禁用按钮,你可以通过以下两种方式解决:
方法一:在视图__init__中修改按钮的禁用状态
先完成视图的初始化,再遍历视图内的组件,找到目标按钮后动态设置其disabled属性:
from discord import ui, app_commands, Interaction import discord class MyClient(discord.Client): async def on_ready(self): await self.wait_until_ready() await tree.sync() print(f"{self.user} on") intents = discord.Intents.all() client = MyClient(intents=intents) tree = app_commands.CommandTree(client) class bigView(ui.View): def __init__(self, a: int, b: int): super().__init__() # 必须先调用父类初始化方法 self.a = a self.b = b # 遍历视图组件,找到"yes"按钮并设置禁用状态 for item in self.children: if isinstance(item, ui.Button) and item.label == "yes": item.disabled = self.a > self.b @ui.button(label="yes") # 装饰器中暂不设置disabled async def yes(self, interaction: Interaction, button: ui.Button): await interaction.response.edit_message(content="yes a is bigger than b") @tree.command(name="big", description="big") async def big(interaction: Interaction, a: int, b: int): await interaction.response.send_message(view=bigView(a, b)) client.run("你的token")
方法二:直接在__init__中创建并添加按钮(更简洁)
跳过装饰器写法,直接在视图初始化时创建按钮,传入动态计算的disabled参数:
from discord import ui, app_commands, Interaction import discord class MyClient(discord.Client): async def on_ready(self): await self.wait_until_ready() await tree.sync() print(f"{self.user} on") intents = discord.Intents.all() client = MyClient(intents=intents) tree = app_commands.CommandTree(client) class bigView(ui.View): def __init__(self, a: int, b: int): super().__init__() self.a = a self.b = b # 直接创建按钮并设置禁用状态,添加到视图 self.add_item(ui.Button( label="yes", disabled=self.a > self.b, callback=self.yes_callback )) async def yes_callback(self, interaction: Interaction): await interaction.response.edit_message(content="yes a is bigger than b") @tree.command(name="big", description="big") async def big(interaction: Interaction, a: int, b: int): await interaction.response.send_message(view=bigView(a, b)) client.run("你的token")
两种方法的核心逻辑一致:在实例创建完成后(即__init__方法内),再根据实例变量设置按钮的禁用状态,避开类定义阶段无法访问self的问题。
内容的提问来源于stack exchange,提问作者bon ho
相关产品推荐
相关产品推荐

