动态处理视图中的多个按钮| Pycord、Discord.py

MrM*_*com 2 python discord discord.py pycord

我正在从 Novus 切换到 Pycord 并尝试转换按钮功能。我正在尝试获取一个列表并添加按钮 1-n 来表示列表的长度,然后获取所选按钮的 custom_id 。选择后,我想继续该命令并在命令的其余部分中使用 custom_id。到目前为止,这就是我所拥有的:

@bot.slash_command(name='bombs', description='Returns bombs to destroy base and airfield.')
async def bomb(ctx):
    await ctx.interaction.response.defer()
    countries = ["America", "Britain", "China", "France", "Germany", "Italy", "Japan", "Russia", "Sweden"]

    view = DefaultView()
    for number in list(range(1, len(countries) + 1)):
        view.add_item(DefaultButton(label=str(number), custom_id=str(number)))
    country_choice_message = await ctx.interaction.followup.send("Select a country to view bombs from:", view=view)

    timed_out_ = await view.wait()
    if timed_out_:
        view.disable_all_items()
        view.stop()
        await country_choice_message.edit(view=view)
        await ctx.interaction.followup.send("Timed out.", ephemeral=True)
        return

    # country_number = button_custom_id
    # do other stuff with country_number...


class DefaultButton(discord.ui.Button):
    def __init__(self, custom_id, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.custom_id = custom_id


class DefaultView(discord.ui.View):
    def __init__(self):
        super().__init__()

    async def callback(self, button: discord.ui.Button, interaction: discord.Interaction):
        self.disable_all_items()
        self.stop()
        await interaction.response.defer()
        await interaction.edit_original_message(view=self)
Run Code Online (Sandbox Code Playgroud)

它根本没有触发视图回调,只是说“此交互失败”。如果我向类添加回调,则DefaultButton()交互不会再失败,但仍然不会返回到命令的其余部分,而只是在回调结束时退出:

class DefaultButton(discord.ui.Button):
    def __init__(self, custom_id, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.custom_id = custom_id

    async def callback(self, interaction: discord.Interaction):
        self.custom_id = interaction.custom_id
        await interaction.response.defer()
        return
Run Code Online (Sandbox Code Playgroud)

然而,超时有效,并在默认(我认为是 180 秒?)等待时间到期后成功禁用所有视图项目。

编辑:我能找到的与此相关的唯一其他帖子是这个。它并不能解决我不知道我可能有多少按钮的问题。如果我这样做了,我可以对所有按钮回调进行硬编码,然后就到此为止了。

编辑:用下面@Ice Wolfy 的答案解决了。完整代码

小智 5

视图不会停止等待,直到超时结束或使用 停止视图View.stop()。要在按钮的回调中执行此操作,请使用self.view.stop(). 文档

您还应该重写on_timeout子类视图中的函数,而不是使用timed_out_变量。这就是 pycord 的意图,并且对 OOP 更友好。 文档