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

如何在Discord.py中点击按钮后禁用或移除原消息的所有按钮?

问题描述

我给Discord机器人设置了两个按钮,需求是点击任意一个后,原消息上的两个按钮都要禁用;如果能直接移除按钮更好,但禁用是必须实现的功能。

当前点击按钮后只会发送响应消息,原消息的按钮仍然可以点击,求解决方案。

当前代码:

import discord
from discord.ext import commands
from discord.ui import Button, button, View

# Class
class MyView(View):
    def __init__(self):
        super().__init__(timeout=None)

    @button(label="Hello!", style=discord.ButtonStyle.blurple)
    async def hello(self, interaction: discord.Interaction, button: Button):
        button.disabled=True
        embedHelloButton=discord.Embed(title="Hi There!", color=0x5865F2)
        embedHelloButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
        await interaction.response.send_message(embed=embedHelloButton, ephemeral=False)
    
    @button(label="No. Bye.", style=discord.ButtonStyle.red)
    async def bye(self, interaction: discord.Interaction, button: Button):
        button.disabled=True
        embedByeButton=discord.Embed(title="Bye :(", color=0xff0000)
        embedByeButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
        await interaction.response.send_message(embed=embedByeButton, ephemeral=False)

# Command
@client.hybrid_command(name="hello", description="Say hello to the bot!")
async def hello(ctx):
    embedHello=discord.Embed(title="Say hello to me!", color=0xff0000)
    embedHello.set_author(name=f"Requested by {ctx.author.name}", icon_url=ctx.author.avatar.url)
    await ctx.send(embed=embedHello, view=MyView())

解决方案

方案1:禁用所有按钮

核心是遍历View中的所有按钮并设置禁用,然后更新原消息的View。修改后的代码如下:

import discord
from discord.ext import commands
from discord.ui import Button, button, View

class MyView(View):
    def __init__(self):
        super().__init__(timeout=None)

    @button(label="Hello!", style=discord.ButtonStyle.blurple)
    async def hello(self, interaction: discord.Interaction, button: Button):
        # 遍历所有组件,禁用所有按钮
        for item in self.children:
            if isinstance(item, Button):
                item.disabled = True
        # 构造响应嵌入
        embedHelloButton=discord.Embed(title="Hi There!", color=0x5865F2)
        embedHelloButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
        # 发送响应并更新原消息的View
        await interaction.response.send_message(embed=embedHelloButton, ephemeral=False)
        await interaction.message.edit(view=self)
    
    @button(label="No. Bye.", style=discord.ButtonStyle.red)
    async def bye(self, interaction: discord.Interaction, button: Button):
        # 遍历所有组件,禁用所有按钮
        for item in self.children:
            if isinstance(item, Button):
                item.disabled = True
        # 构造响应嵌入
        embedByeButton=discord.Embed(title="Bye :(", color=0xff0000)
        embedByeButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
        # 发送响应并更新原消息的View
        await interaction.response.send_message(embed=embedByeButton, ephemeral=False)
        await interaction.message.edit(view=self)

@client.hybrid_command(name="hello", description="Say hello to the bot!")
async def hello(ctx):
    embedHello=discord.Embed(title="Say hello to me!", color=0xff0000)
    embedHello.set_author(name=f"Requested by {ctx.author.name}", icon_url=ctx.author.avatar.url)
    await ctx.send(embed=embedHello, view=MyView())

关键说明

  • 仅设置当前点击的button.disabled=True无效,必须遍历self.children(View的所有子组件),把所有Button标记为禁用
  • 通过interaction.message.edit(view=self)更新原消息的View,让禁用状态生效

方案2:移除所有按钮

如果需要直接移除按钮,只需在更新原消息时传入view=None,即可清空原消息的所有按钮。修改后的回调示例:

@button(label="Hello!", style=discord.ButtonStyle.blurple)
async def hello(self, interaction: discord.Interaction, button: Button):
    embedHelloButton=discord.Embed(title="Hi There!", color=0x5865F2)
    embedHelloButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
    await interaction.response.send_message(embed=embedHelloButton, ephemeral=False)
    # 移除原消息的所有按钮
    await interaction.message.edit(view=None)

@button(label="No. Bye.", style=discord.ButtonStyle.red)
async def bye(self, interaction: discord.Interaction, button: Button):
    embedByeButton=discord.Embed(title="Bye :(", color=0xff0000)
    embedByeButton.set_author(name=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
    await interaction.response.send_message(embed=embedByeButton, ephemeral=False)
    # 移除原消息的所有按钮
    await interaction.message.edit(view=None)

关键说明

  • view=None会让Discord移除原消息上的整个View,所有按钮自然消失
  • 此方案不需要处理按钮禁用状态,直接移除更彻底

内容的提问来源于stack exchange,提问作者Harri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:23:16