Buttons

How to use Buttons with Pycord

This guide has been moved to https://namantech.me/pycord. Please visit the new guide instead, since this one might be outdated.

The new guide looks better, has better explanations, and is way better overall.

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

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

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

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