pythondiscord.py

Why am I getting errors with discord.ActionRow in discord.py?


I'm trying to create a game using buttons in Discord with discord.py, and I'm using discord.ActionRow, but it's giving me errors. Here's the function for context:

async def create_game_board(self, view, callback):
        buttons = []
        for i in range(3):
            row_buttons = []
            for j in range(3):
                button = discord.ui.Button(label="\u200b", style=discord.ButtonStyle.gray, custom_id=f"{i}_{j}")
                button.callback = callback
                row_buttons.append(button)
            buttons.append(row_buttons)
        print(len(buttons[0]))
        view.add_item(discord.ActionRow(*buttons[0]))
        view.add_item(discord.ActionRow(*buttons[1]))
        view.add_item(discord.ActionRow(*buttons[2]))
        return buttons

My problem lies in this code snippet

view.add_item(discord.ActionRow(*buttons[0]))
view.add_item(discord.ActionRow(*buttons[1]))
view.add_item(discord.ActionRow(*buttons[2]))

But it results in this error:

File "Removed for StackOverflow", line 111, in create_game_board
    view.add_item(discord.ActionRow(*buttons[0]))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: ActionRow.__init__() takes 2 positional arguments but 4 were given

I've also tried doing discord.ActionRow(components=buttons[0]) but that results in errors too.


Solution

  • It seems ActionRow() doesn't work like in some old tutorials.

    But it seems it is used only by inner code and you don't have to use it at all.
    You should directly put button in view and use Button(..., row=number)

    button = discord.Button(..., row=y)
    
    view.add_item(button)
    

    Minimal working code

    Tested with discord.py 2.5.1, py-cord 2.6.1, nextcord 3.1.0

    import os
    
    import discord                      # for discord.py and py-cord
    from discord.ext import commands    # for discord.py and py-cord
    #import nextcord as discord         # for nextcord
    #from nextcord.ext import commands  # for nextcord
    
    print('discord version:', discord.__version__)
    
    # https://discordpy.readthedocs.io/en/stable/logging.html#logging-setup
    import logging
    logging.basicConfig(level=logging.INFO)
    
    TOKEN = os.getenv('DISCORD_TOKEN')
    
    intents = discord.Intents.default()
    intents.message_content = True
    
    bot = commands.Bot(command_prefix="!", intents=intents)
    
    # ---------------------------------------------
    
    class MyView(discord.ui.View):
        def __init__(self):
            super().__init__()
    
            for y in range(3):
                for x in range(3):
                    button = discord.ui.Button(
                        label=f"Button {y+1}.{x+1}",
                        #style=discord.ButtonStyle.primary,
                        style=discord.ButtonStyle.gray, 
                        custom_id=f"{y}_{x}",
                        row=y
                    )
                    self.add_item(button)
    
    # ---------------------------------------------
    
    @bot.event
    async def on_ready():
        print("[on_ready] ready as", bot.user.name)
    
    @bot.command()
    async def button(ctx):
        view = MyView()
        msg = await ctx.send(view=view)
    
    # ---------------------------------------------
    
    bot.run(TOKEN)
    

    enter image description here