#Add buttons to view dynamically
1 messages · Page 1 of 1 (latest)
yes
You can create buttons with button = discord.ui.Button(…) and add buttons view.add_item(button)
thanks
but how do I handle callbacks
How can I make the button do something with this method?
Thanks
like this button = discord.ui.Button(button.callback == test_interaction(), label=RolesV2[i])?
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```
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'```
You need to initialise the view to a variable first, you have the order all wrong
e.g. view = RoleView() -> view.add_item(...)
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
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
🤦♂️ of course... thank you so much
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)
By doing that should I then use self instead of view = RoleView() ?
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
Ahh thanks. That works. When using button.callback == test_interaction does the test_interaction function recieve interaction as an agument?
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)
what type is custom_id?
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
Ok
does the button.callback function have to be inside the RoleView or can it be outside the Roleview class
Uhh as long as it's accessible you could have it outside
ok
Though it might make more sense to have it inside? Unless you're using it elsewhere
so if it's inside should it then be button.callback == self.test_interaction
Mhm
or do you mean having it inside init?
Nah, should be in-line with init
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)
Yeah seems good
when pressing any of the button I just get interaction failed and nothing is printed
and I don't get any errors in python
Oh callback function needs to be async
like async def?
Mhm
that still gives the same error
Hmmm
PyCharm is also saying statement seems to have no effect
Not sure if that has something to with it
Yes
Can you try responding to the interaction in the callback
interaction.response.send_message("test")
print(interaction.user)
print(self.get_item(interaction.custom_id))```
it fails too
Can you remove button.callback = ..., and rename the callback function to interaction_check
Wait
...
You're using ==, not =
🤦♂️
That's why pycharm warned you LOL
lol