#Add buttons to view dynamically

1 messages · Page 1 of 1 (latest)

unreal mica
#

I have a discord bot where I need to add some buttons from a list. Is it possible to add them dynamically like for button in buttons: add button or do I have to hardcode them all in?

I am new to pycord and have done this before with reactions and discord.py

glass bronze
#

You can create buttons with button = discord.ui.Button(…) and add buttons view.add_item(button)

unreal mica
#

but how do I handle callbacks

#

How can I make the button do something with this method?

glass bronze
#

button.callback = func

#

the func should only take an interaction object

unreal mica
#

Thanks

unreal mica
#

that gives

button = discord.ui.Button(button.callback == test_interaction(), label=RolesV2[i])
                               ^^^^^^
UnboundLocalError: cannot access local variable 'button' where it is not associated with a value```
glass bronze
#

no, the button assignment should be on the next line

#

and without the parentheses

unreal mica
#

Ok that works.
the add_item() function fails tho
My code is

@bot.command()
async def roles(ctx):
    for i in range(0, len(emoji_to_role_dict)):
        button = discord.ui.Button(label=RolesV2[i])
        button.callback == test_interaction
        RoleView.add_item(button)
    await ctx.respond(view=RoleView())```
It fails with ```  File "/home/[USERNAME]/wc/[SVN_REPO]/kode/PycharmProjects/DiscordBotRdaf/main.py", line 355, in roles
    RoleView.add_item(button)
TypeError: View.add_item() missing 1 required positional argument: 'item'```
short niche
#

e.g. view = RoleView() -> view.add_item(...)

unreal mica
# short niche You need to initialise the view to a variable first, you have the order all wron...

Is this the right order?

class RoleView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)  # timeout of the view must be set to None

@bot.command()
async def roles(ctx):
    for i in range(0, len(emoji_to_role_dict)):
        button = discord.ui.Button(label=RolesV2[i])
        button.callback == test_interaction
        view = RoleView()
        view.add_item(item=button)
        print(i)
    button2 = discord.ui.Button(label="Test")
    button2.callback == test_interaction
    view2 = RoleView()
    view2.add_item(item=button2)
    await ctx.respond(view=RoleView())
```?
#

it just doesn't seem to add any buttons to the view

short niche
#

Why are you creating two views

#

...3 views

unreal mica
#

just to test if it was the for loop that was failing

#

It's just debug

short niche
#

You seem to be misunderstanding how creating an instance works? If you create one RoleView(), you should keep using that for the rest of the command - so create the view before the loop

#

There's no buttons because you created another new RoleView in your send function

unreal mica
#

🤦‍♂️ of course... thank you so much

short niche
#

Allgood (also i would personally restructure it so RoleView accepts a list of roles, then you can manage it all inside the view, but if you're not reusing it elsewhere then this works too)

unreal mica
short niche
#

Uhhh not quite

#

To accomplish that, you would add a new argument to your view's init (e.g. self, roles) and then you can loop through it and do self.add_item inside the init

#

You would still need view =, but it'd be more like view = RoleView(emoji_to_role_dict) and no extra processing in the command

unreal mica
#

Ahh thanks. That works. When using button.callback == test_interaction does the test_interaction function recieve interaction as an agument?

short niche
#

Yep, when assigning callbacks like that it only takes interaction

#

Ideally you should set the button's custom_id to identify what was pressed, but if you haven't and instead want to get the button object you can do self.get_item(interaction.custom_id)

unreal mica
#

what type is custom_id?

short niche
#

It's a string, designed for you to manually set it to identify the interaction but if you don't the library will set it to a random string

unreal mica
#

Ok

#

does the button.callback function have to be inside the RoleView or can it be outside the Roleview class

short niche
#

Uhh as long as it's accessible you could have it outside

unreal mica
#

ok

short niche
#

Though it might make more sense to have it inside? Unless you're using it elsewhere

unreal mica
#

so if it's inside should it then be button.callback == self.test_interaction

short niche
#

Mhm

unreal mica
#

or do you mean having it inside init?

short niche
#

Nah, should be in-line with init

unreal mica
#

ok

#

So like this? class RoleView(discord.ui.View): def test_interaction(self, interaction): print(interaction.user) print(self.get_item(interaction.custom_id)) def __init__(self, roles): super().__init__(timeout=None) # timeout of the view must be set to None for i in range(0, len(roles)): if i == 20: break button = discord.ui.Button(label=RolesV2[i], custom_id=RolesV2[i]) button.callback == self.test_interaction self.add_item(item=button) print(i)?

#

(just breaking the loop at 20 temporarialy)

short niche
#

Yeah seems good

unreal mica
#

when pressing any of the button I just get interaction failed and nothing is printed

#

and I don't get any errors in python

short niche
#

Oh callback function needs to be async

unreal mica
#

like async def?

short niche
#

Mhm

unreal mica
#

that still gives the same error

short niche
#

Hmmm

unreal mica
#

PyCharm is also saying statement seems to have no effect

#

Not sure if that has something to with it

short niche
#

Probably not

#

The view still sends normally?

unreal mica
#

Yes

short niche
#

Can you try responding to the interaction in the callback

unreal mica
#
        interaction.response.send_message("test")
        print(interaction.user)
        print(self.get_item(interaction.custom_id))```
#

it fails too

short niche
#

Need to await that

#

But hmm

unreal mica
#

it sadly still fails with await

#

and doesn't send anything

short niche
#

Can you remove button.callback = ..., and rename the callback function to interaction_check

#

Wait

#

...

#

You're using ==, not =

unreal mica
#

🤦‍♂️

short niche
#

That's why pycharm warned you LOL

unreal mica
#

lol