Search code examples
pythonbuttondiscorddiscord.pypokeapi

how to disable specific buttons with discord.py bot


I would like to know if there is a way for me to disable a button after I click on another one. Example:

enter image description here

when I click on the stats button, I need the shiny button to be disabled!

I did something similar, however for the same button I clicked:

enter image description here

I used the button.disabled = True and it worked, but to disable another button also by clicking on the stats button, I couldn't! Can you help?


Solution

  • So, assuming you have a View class that inherits from discord.ui.View and your buttons are defined like the following. We can use the self property on the View class to get the view's children (ie; buttons, selects, etc) and then iterate over them and looking for buttons that have the shiny label.

    class View(discord.ui.View):
        def __init__(self):
            super().__init__()
    
        @discord.ui.button(label="shiny")
        async def shiny_callback(self, button: discord.ui.Button, interaction: discord.Interaction):
            pass
    
        @discord.ui.button(label="stats")
        async def stats_callback(self, button: discord.ui.Button, interaction: discord.Interaction):
            # defer whilst we work out stats stuff
            await interaction.response.defer()
    
            message = interaction.message
    
            # find the shiny button and disable it
            # keep a reference to the right button in case we want to enable it later
            shiny_button = None
            for child in self.children:
                if type(child) == discord.ui.Button and child.label == "shiny":
                    shiny_button = child
                    child.disabled = True
                    break
    
            # update the view in discord
            await interaction.message.edit(content=message.content, view=self)
    
            # do the rest of what the `stats` button should do
    
            # actually send followup message to user
            await interaction.followup.send("stats")
    
            # if we wanted to re-enable the other button we can do it here
            # commented out
            # shiny_button.disabled = False
            # await interaction.message.edit(content=message.content, view=self)
    
    
        @discord.ui.button(label="back")
        async def back_callback(self, button: discord.ui.Button, interaction: discord.Interaction):
            pass
    

    The example is quite simple; we defer to stop discord complaining we didn't respond, then we do what I said and then edit the message immediately to disable the shiny button to prevent anyone from pressing it. Then you can do your logic. then we can send our followup message to let the user know we did what we should have done. And then, optionally, we re-enable the button again.