Discord buttons position discord py

i need help on my code. Im trying to do buttons for my discord bot. I managed to do it but i want to add something new. As you can see b1 will always be on the left , b2 on the middle and b3 on the right. Is it possible to shuffle the buttons position every time user enter a command. Any help would be appreciated. Below i attached my code. Thanks !

class ButtonView(discord.ui.View):
    def __init__(self, code, *, timeout=20):
        super().__init__(timeout=timeout)
        self.code = code
        self.solved = None
        self.failed = 0

        self.b1.label = code
        self.b2.label="".join(random.sample(string.digits, 4))
        self.b3.label="".join(random.sample(string.digits, 4))

    @discord.ui.button(style=discord.ButtonStyle.gray)
    async def b1(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.send_message("Good!!")
        self.solved = True
        self.stop()

    @discord.ui.button(style=discord.ButtonStyle.gray)
    async def b2(self, interaction: discord.Interaction, button: discord.ui.Button):
        self.failed += 1
        if self.failed >= 2:
            await interaction.response.send_message(f"Too many incorrect attempts. Kicking {interaction.user.mention}")
            await interaction.user.kick(reason="Too many incorrect captcha attempts.")
            await log_attempt(interaction.user, success=False)
        else:
            await interaction.response.send_message("Wrong!!")
            self.solved = False
            if self.failed >= 2:
                self.stop()

    @discord.ui.button(style=discord.ButtonStyle.gray)
    async def b3(self, interaction: discord.Interaction, button: discord.ui.Button):
        self.failed += 1
        if self.failed >= 2:
            await interaction.response.send_message(f"Too many incorrect attempts. Kicking {interaction.user.mention}")
            await interaction.user.kick(reason="Too many incorrect captcha attempts.")
            await log_attempt(interaction.user, success=False)
        else:
            await interaction.response.send_message("Also wrong!!")
            self.solved = False
            if self.failed >= 2:
                self.stop()

  • you cannot randomize/shuffle button’s position. you can only change the row of the button, not the position of buttons in the same row. You could choose to shuffle the label/functionalities of the button to work around this I think.

    – 

  • that’s brilliant, thanks for your help Tim !

    – 

By adding the buttons dynamically, you can change the order in which they are added to the view.

import random

class ButtonView(discord.ui.View):
    def __init__(self):
        super().__init__()
        self.add_buttons()

    def add_buttons(self):
        buttons = [
            discord.ui.Button(label="Button 1"),
            discord.ui.Button(label="Button 2"),
            discord.ui.Button(label="Button 3")
        ]
        buttons[0].callback = ... #  Or set them as variables first 
        buttons[1].callback = ... #  then put them into a list
        buttons[2].callback = ...
        random.shuffle(buttons) #  Randomises the order
        for button in buttons:
            self.add_item(button)

This example uses the function add_buttons to dynamically add the buttons to the view as it is being initialised.

The view will show the buttons in order of them being added; just like how you did with the button decorators, the buttons here are in a list and then shuffled into a random order to be added.

If randomisation is not what you were looking for, you can also use the same method to change which buttons are which.

def add_buttons(self):
    if ...: #  Some condition
        button = ... #  Button object
        button.callback = ... #  Callback function
        self.add_item(button)

The for loop is also not needed, as long as the buttons are added to the view class in a specific order, they will appear in that order.

Leave a Comment