Search code examples
pythondrop-down-menudiscord.pypycord

How to make pycord select menu disable the menu on timeout


I have a pycord dropdown menu and I cant find how to set the timeout and how to make the button disable on timeout, and I can't find where I am supposed to add the timeout amount.

code:


class Dropdown(discord.ui.Select):
    def __init__(self, bot, timeout=1):
        # For example, you can use self.bot to retrieve a user or perform other functions in the callback.
        self.bot = bot
        self.inter = None

        # Alternatively you can use Interaction.client, so you don't need to pass the bot instance.
        # Set the options that will be presented inside the dropdown
        options = [
            discord.SelectOption(
                label="Red", description="Your favourite colour is red", emoji="🟥"),
            discord.SelectOption(
                label="Green", description="Your favourite colour is green", emoji="🟩"),
            discord.SelectOption(
                label="Blue", description="Your favourite colour is blue", emoji="🟦"),
        ]

        # The placeholder is what will be shown when no option is chosen
        # The min and max values indicate we can only pick one of the three options
        # The options parameter defines the dropdown options. We defined this above
        super().__init__(
            placeholder="Choose your favourite colour...",
            min_values=1,
            max_values=1,
            options=options,


        )

    async def callback(self, interaction: discord.Interaction):
        # Use the interaction object to send a response message containing
        # The user's favourite colour or choice. The self object refers to the
        # Select object, and the values attribute gets a list of the user's
        # selected options. We only want the first one.
        await interaction.response.send_message(f"Your favourite colour is {self.values[0]}")

    async def on_timeout(self):
        print("test")


class DropdownView(discord.ui.View):
    def __init__(self, bot):
        self.bot = bot
        super().__init__()

        # Adds the dropdown to our view object.
        self.add_item(Dropdown(self.bot))


@bot.slash_command(guild_ids=[954586898549059594])
async def button(ctx):
    await ctx.defer()
    view = DropdownView(bot)

    # Sending a message containing our view
    await ctx.followup.send("Pick your favourite colour:", view=view)```

Solution

  • In the Pycord documentation about the Select class, there isn't the timeout property mentioned.

    Timeout is a property of the View class and you can therefore use its on_timeout method to disable your Select menu.

    By using the clear_items function, the menu will be disabled on timeout.

    The code below will not execute the callback.

    class Dropdown(discord.ui.Select):
        def __init__(self, bot):
            # For example, you can use self.bot to retrieve a user or perform other functions in the callback.
            self.bot = bot
            self.inter = None
    
            # Alternatively you can use Interaction.client, so you don't need to pass the bot instance.
            # Set the options that will be presented inside the dropdown
            options = [
                discord.SelectOption(
                    label="Red", description="Your favourite colour is red", emoji="🟥"),
                discord.SelectOption(
                    label="Green", description="Your favourite colour is green", emoji="🟩"),
                discord.SelectOption(
                    label="Blue", description="Your favourite colour is blue", emoji="🟦"),
            ]
    
            # The placeholder is what will be shown when no option is chosen
            # The min and max values indicate we can only pick one of the three options
            # The options parameter defines the dropdown options. We defined this above
            super().__init__(
                placeholder="Choose your favourite colour...",
                min_values=1,
                max_values=1,
                options=options 
    
    
            )
    
        async def callback(self, interaction: discord.Interaction):
            # Use the interaction object to send a response message containing
            # The user's favourite colour or choice. The self object refers to the
            # Select object, and the values attribute gets a list of the user's
            # selected options. We only want the first one.
            await interaction.response.send_message(f"Your favourite colour is {self.values[0]}")
    
    
    class DropdownView(discord.ui.View):
        def __init__(self, bot, timeout=1):
            self.bot = bot
            super().__init__(timeout=timeout)
    
            # Adds the dropdown to our view object.
            self.add_item(Dropdown(self.bot))
    
        async def on_timeout(self):
            print("test")
            self.clear_items()