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

如何在discord.py中根据变量条件禁用Button组件?

解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:52:51