Buttons

How to use Buttons with Pycord

Docs: https://pycord.readthedocs.io/en/master/api.html#discord.Button

Credits: https://gist.github.com/MhmCats/500eafdad0aaf278b94c612764688976

Button Attributes

Sub-Classing discord.ui.View

class MyView(discord.ui.View):
    @discord.ui.button(label='A button', style=discord.ButtonStyle.primary, emoji='😎')
    async def button_callback(self, button, interaction):
        await interaction.response.send_message('Button was pressed', ephemeral=True)

view = MyView()
@bot.command()
async def button(ctx):
    await ctx.send('Press the button!', view=view)

Sub-Classing discord.ui.Button

class MyButton(discord.ui.Button):
    def __init__(self):
        super().__init__(label='A button', style=discord.ButtonStyle.primary)

    async def callback(self, interaction):
        await interaction.response.send_message('Button was pressed', ephemeral=True)

view = discord.ui.View()
view.add_item(MyButton())
@bot.command()
async def ctx.send('Press the button!', view=view)

Using buttons with subclassing

view = discord.ui.View()
view.add_item(discord.ui.Button(label='Go to website', url='https://gist.github.com/MhmCats/500eafdad0aaf278b94c612764688976', style=discord.ButtonStyle.url))

Button Styles

Button styles can be one of these

Styles

Name

Usage

Color

Primary

discord.ButtonStyle.primary

Blurple

Secondary

discord.ButtonStyle.secondary

Grey

Success

discord.ButtonStyle.success

Green

Danger

discord.ButtonStyle.danger

Red

Link

discord.ButtonStyle.link

Grey

URL Buttons

view = discord.ui.View()
view.add_item(discord.ui.Button(label='Go to website', url='https://gist.github.com/MhmCats/500eafdad0aaf278b94c612764688976', style=discord.ButtonStyle.url))

@bot.command()
async def url(ctx):
    await ctx.send(content="Press the button!", view=view)

Disabling Buttons

Disabling Buttons on Click

Here's how you can disable a single button or multiple buttons on press:

class MyView(discord.ui.View):
    @discord.ui.button(label='A button', style=discord.ButtonStyle.primary)
    async def button_callback(self, button, interaction):
        button.disabled = True
        button.label = 'No more pressing!'
        await interaction.response.edit_message(view=self)
        
view = MyView()
@bot.command()
async def button(ctx):
    await ctx.send('Press the button!', view=view)

Making Pre-Disabled Buttons

class MyView(discord.ui.View):
    @discord.ui.button(label='A button', style=discord.ButtonStyle.primary, disabled=True)
    async def button_callback(self, button, interaction):
        ...
        
view = MyView()
@bot.command()
async def button(ctx):
    await ctx.send('Press the button!', view=view)

Timeouts

You probably wanna set a timeout too, and its quite simple, really!

class MyView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=10)
    async def on_timeout(self):
        for child in self.children:
            child.disabled = True
        await self.message.edit(view=self)

    @discord.ui.button(style=discord.ButtonStyle.primary, emoji=':sunglasses:')
    async def callback(self, button, interaction):
        await interaction.response.send_message('Button was pressed', ephemeral=True)


@bot.command()
async def hi(ctx):
    view = MyView()
    view.message = await ctx.send("hi", view=view)

Rows

A message can have up to five "action rows" and each of these "action" rows have five slots where you can put message components. A button takes up one of these slots but a select menus takes up all five slots of a "action row". Keep this in mind when creating your views since you don't want to run out of space!

class MyView(discord.ui.View):

    @discord.ui.button(label="Button 1",
                       style=discord.ButtonStyle.primary, row=1)
    async def first_button_callback(self, button, interaction):
        await interaction.response.send("You pressed me!")

    @discord.ui.button(label="Button 2",
                       style=discord.ButtonStyle.primary, row=2)
    async def second_button_callback(self, button, interaction):
        await interaction.response.send("You pressed me!")
        
@bot.command()
async def button(ctx):
    view.message = await ctx.send("Wow!", view=MyView())

Last updated

Was this helpful?