Discord.py v2中同时使用按钮与下拉菜单的问题求助
问题分析
你不能把两个View实例放进列表传给view参数,因为Discord.py的send_message()方法要求view必须是单个discord.ui.View对象,列表类型不被支持,这就是两者一起用失效的核心原因。
解决方法
有两种可行的方式把按钮和下拉菜单整合到同一个View中:
方法一:创建统一的HelpView类
直接把按钮和下拉选择菜单的定义放到同一个View类里,实例化一次就能同时包含两种组件:
import discord from discord import app_commands import random class HelpView(discord.ui.View): def __init__(self, *, timeout=15): super().__init__(timeout=timeout) self.click = False # 下拉选择菜单 @discord.ui.select( placeholder='Select a category', options=[ discord.SelectOption(label='Guns', value="1", description='Dangerous Guns stolen from the government', emoji='<:golden_sniper:1123954953640218724>'), discord.SelectOption(label='Drugs', value="2", description='Drugs that can be used to get high', emoji='<:weed:1124062866505486356>'), discord.SelectOption(label='Swords', value="3", description='The Ancient Blades of Death', emoji='⚔️'), ] ) async def select_option_callback(self, interaction: discord.Interaction, select: discord.ui.Select): if select.values[0] == "1": snack_embed = discord.Embed(title='Guns', description='Reload em', color=discord.Color.random()) await interaction.response.edit_message(embed=snack_embed, view=self) elif select.values[0] == "2": snack_embed = discord.Embed(title='Drugs', description='Get High', color=discord.Color.random()) await interaction.response.edit_message(embed=snack_embed, view=self) elif select.values[0] == "3": snack_embed = discord.Embed(title='Swords', description='Ancient Blades of Death', color=discord.Color.random()) await interaction.response.edit_message(embed=snack_embed, view=self) # 按钮组件(保留原Rock按钮逻辑,可按需修改) @discord.ui.button(label="Rock🗿", style=discord.ButtonStyle.green, custom_id="easy") async def rock_button(self, interaction: discord.Interaction, child: discord.ui.Button): for child in self.children: child.disabled=True win_embed = discord.Embed(title="You win 🎉!", description="**Your Choice:** Rock🗿\n**Xynox Choice:** Scissors✂️", color=discord.Color.green()) loss_embed = discord.Embed(title="You lose 😭!", description="**Your Choice:** Rock🗿\n**Xynox Choice:** Paper📄", color=discord.Color.red()) tie_embed = discord.Embed(title="It's a tie 🤝!", description="**Your Choice:** Rock🗿\n**Xynox Choice:** Rock🗿", color=discord.Color.blurple()) embed = random.choice([win_embed, loss_embed, tie_embed]) await interaction.response.edit_message(embed=embed, view=self) class Help(commands.Cog): def __init__(self, client): self.client = client @app_commands.command(name='help', description='Gives info about all the commands') async def help(self, interaction: discord.Interaction): embed = discord.Embed(title="Help", description="Use the dropdown to select a category", color=discord.Color.random()) await interaction.response.send_message(embed=embed, view=HelpView())
方法二:合并已有View的组件
如果不想重构类,可以把一个View里的组件添加到另一个View中:
# 保留你原有的Buttons和categorySelect类不变 class help(commands.Cog): def __init__(self, client): self.client = client @app_commands.command(name='help', description='Gives info about all the commands') async def help(self, interaction: discord.Interaction): embed = discord.Embed(title="Help", description="Use the dropdown to select a category", color=discord.Color.random()) # 创建主View实例 main_view = discord.ui.View(timeout=15) # 添加下拉菜单组件 category_menu = categorySelect() main_view.add_item(category_menu.children[0]) # 添加按钮组件 rock_button = Buttons() main_view.add_item(rock_button.children[0]) # 发送消息 await interaction.response.send_message(embed=embed, view=main_view)
额外注意事项
- 原代码中
categorySelect类的继承需确保是discord.ui.View,若导入时用了from discord.ui import View则无需修改,否则要补全路径。 - 下拉菜单回调里重复创建
categorySelect()会导致每次选择后重置View,若想保留按钮,应使用当前的self而非新实例。
内容的提问来源于stack exchange,提问作者TalhaIqbal
相关产品推荐
相关产品推荐

