How to call a function in a cog from a view using Nextcord?

Question:

I have a Cog and a view in nextcord. I’m trying to call the function magic_function from my view, but I’ve found no way of achieving it. Do you know how is it possible ?
Here is a simplification of the situation :

class MyView(nextcord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)
    
    @nextcord.ui.button(label='Send Magic', style=nextcord.ButtonStyle.primary)
    async def magicbutton(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        magic_word = MyCog.get_magic_word() # Here, I would like to access MyCog, but can't figure how
        await interaction.response.send_message(magic_word)


class MyCog(commands.Cog):
    def __init__(self, client):
        self.client = client

    def get_magic_word(self):
        # Doing stuff
        return "Banana"

    @nextcord.slash_command(description="Sends the button")
    async def send_the_view(self, interaction: nextcord.Interaction):
        view = MyView()
        await interaction.response.send_message("Here is the view :", view=view)


def setup(client):
    client.add_cog(MyCog(client=client))

I thought I could define my view inside the Cog, but I find it useless, since i coulden’t access the function either. Also, I thought I could bring the function get_magic_word() outside the cog, but this is a bad idea since the function needs to call self to do stuff.

Asked By: Deden

||

Answers:

An easy way to do this is to provide the view with a reference to the instantiated Cog object:

class MyView(nextcord.ui.View):
    def __init__(self, my_cog):
        super().__init__(timeout=None)
        self.my_cog = my_cog  # store the cog object as a class variable

    @nextcord.ui.button(label='Send Magic', style=nextcord.ButtonStyle.primary)
    async def magicbutton(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        magic_word = self.my_cog.get_magic_word()  # interact with the cog object
        await interaction.response.send_message(magic_word)


class MyCog(commands.Cog):
    def __init__(self, client):
        self.client = client

    def get_magic_word(self):
        # Doing stuff
        return "Banana"

    @nextcord.slash_command(description="Sends the button")
    async def send_the_view(self, interaction: nextcord.Interaction):
        view = MyView(self)  # pass self to the view
        await interaction.response.send_message("Here is the view :", view=view)

This way, MyView can access methods/attributes on the instantiated MyCog.

Answered By: ESloman
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.