You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Discord Python选择菜单中实现二级嵌套选择功能?

实现Discord选择菜单的二级嵌套交互

要实现选择首个选项后弹出二级选择的效果,核心思路是在一级菜单的回调中动态更新消息的View,替换成二级选择菜单。以下是修改后的完整代码:

import discord
from discord.ext import commands

# 一级选择菜单
class FirstDropdown(discord.ui.Select):
    def __init__(self):
        options = [
            discord.SelectOption(label='Акрополь', description='Выберите вариант баннера "Акрополь"', emoji='🏛️'),
            discord.SelectOption(label='Год Кролика', description='Будет отправлен баннер "Год Кролика"', emoji='🐇'),
            discord.SelectOption(label='Зевс', description='Будет отправлен баннер "Зевс"', emoji='⚡'),
        ]
        super().__init__(placeholder='Выберите нужный баннер:', min_values=1, max_values=1, options=options)

    async def callback(self, interaction: discord.Interaction):
        if self.values[0] == 'Акрополь':
            # 清空当前View的所有组件,添加二级选择菜单
            self.view.clear_items()
            self.view.add_item(SecondDropdown())
            # 更新消息内容和View,引导用户选择子选项
            await interaction.response.edit_message(content='Выберите вариант баннера "Акрополь":', view=self.view)
        elif self.values[0] == 'Год Кролика':
            await interaction.response.send_message('Баннер "Год Кролика"', file=discord.File(r'C:\Users\Timir\AppData\Local\Discord\Kroll.png'))
        elif self.values[0] == 'Зевс':
            await interaction.response.send_message('Баннер "Зевс"', file=discord.File(r'C:\Users\Timir\AppData\Local\Discord\Zevs.png'))

# 二级选择菜单(仅针对"Акрополь"选项)
class SecondDropdown(discord.ui.Select):
    def __init__(self):
        # 自定义二级选项,可根据需求修改
        options = [
            discord.SelectOption(label='Акрополь - Дневной', description='Дневная версия баннера', emoji='☀️'),
            discord.SelectOption(label='Акрополь - Ночной', description='Ночная версия баннера', emoji='🌙'),
        ]
        super().__init__(placeholder='Выберите вариант:', min_values=1, max_values=1, options=options)

    async def callback(self, interaction: discord.Interaction):
        # 根据二级选择发送对应文件
        if self.values[0] == 'Акрополь - Дневной':
            await interaction.response.send_message('Баннер "Акрополь - Дневной"', file=discord.File(r'C:\Users\Timir\AppData\Local\Discord\Akropol_day.png'))
        elif self.values[0] == 'Акрополь - Ночной':
            await interaction.response.send_message('Баннер "Акрополь - Ночной"', file=discord.File(r'C:\Users\Timir\AppData\Local\Discord\Akropol_night.png'))

# 视图类,用于承载选择菜单
class DropdownView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=180)  # 设置3分钟超时,可调整
        self.add_item(FirstDropdown())

# 初始化机器人
intents = discord.Intents.all()
intents.message_content = True
bot = commands.Bot(command_prefix='+', intents=intents)

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user} (ID: {bot.user.id})')
    print('------')

@bot.command()
async def banner(ctx):
    """Отправляет сообщение с выбором баннера"""
    view = DropdownView()
    await ctx.send('Выберите нужный баннер:', view=view)

@bot.command()
async def Молодец(ctx):
    await ctx.send(f"{ctx.author.mention} молодец")

bot.run('bottoken')

关键改动说明

  1. 拆分选择菜单类:将原来的单一Dropdown拆分为FirstDropdown(一级菜单)和SecondDropdown(二级菜单),分别处理不同层级的选择逻辑。
  2. 动态更新View:在一级菜单的callback中,当用户选择"Акрополь"时,调用self.view.clear_items()清空当前视图组件,再添加二级菜单,最后用interaction.response.edit_message()更新原消息的内容和视图。
  3. 修复重复初始化问题:删除冗余的Bot类定义,统一使用bot = commands.Bot()初始化,并通过@bot.event定义on_ready事件。
  4. 设置超时时间:给DropdownView设置180秒超时,避免视图长时间无效占用资源。

注意事项

  • 请确保二级菜单对应的图片文件路径正确,否则会抛出文件不存在的错误。
  • 如果需要扩展更多层级嵌套,可按照相同逻辑继续添加新的选择菜单类,并在对应回调中更新视图。

内容的提问来源于stack exchange,提问作者Oskar Voralberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:01:05