如何在Discord.py中将变量传入Modal的on_submit()方法?
解决Discord Modal自定义__init__传参时的AttributeError问题
错误原因
自定义ModalApplicationForm的__init__方法时,未调用父类discord.ui.Modal的构造函数,导致Modal类必需的核心属性(如custom_id)未被初始化,从而触发AttributeError。
修正方案
在自定义的__init__方法中,必须先调用super().__init__()完成父类初始化,再添加自定义变量。同时可将角色ID等需要传递的参数传入,供on_submit方法使用。
完整修正代码
import discord from discord.ext import commands from discord import ui intents = discord.Intents.default() intents.members = True intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) @bot.event async def on_ready(): bot.add_view(ViewAllianceSelection()) await bot.tree.sync() # 角色选择视图 class ViewAllianceSelection(discord.ui.View): def __init__(self): super().__init__(timeout=None) # 示例三个角色按钮,custom_id替换为实际角色ID @discord.ui.button(label="联盟1", custom_id="123456789012345678", style=discord.ButtonStyle.green) async def role1_btn(self, interaction: discord.Interaction, button: discord.Button): # 将按钮的custom_id(角色ID)传入Modal await interaction.response.send_modal(ModalApplicationForm(target_role_id=button.custom_id)) @discord.ui.button(label="联盟2", custom_id="987654321098765432", style=discord.ButtonStyle.blue) async def role2_btn(self, interaction: discord.Interaction, button: discord.Button): await interaction.response.send_modal(ModalApplicationForm(target_role_id=button.custom_id)) @discord.ui.button(label="联盟3", custom_id="112233445566778899", style=discord.ButtonStyle.red) async def role3_btn(self, interaction: discord.Interaction, button: discord.Button): await interaction.response.send_modal(ModalApplicationForm(target_role_id=button.custom_id)) # 申请Modal class ModalApplicationForm(discord.ui.Modal, title='联盟申请表单'): def __init__(self, target_role_id): # 先调用父类构造函数,初始化Modal必要属性 super().__init__(title=self.title) # 保存自定义变量:目标角色ID self.target_role_id = target_role_id # 添加文本输入组件 self.submittedUN = ui.TextInput(label='输入你的用户名', style=discord.TextStyle.short) self.add_item(self.submittedUN) async def on_submit(self, interaction: discord.Interaction): # 获取用户输入的用户名 username = self.submittedUN.value # 获取目标角色 target_role = interaction.guild.get_role(int(self.target_role_id)) if target_role: # 为用户分配角色 await interaction.user.add_roles(target_role) # 存入数据库(替换为你的实际数据库逻辑) print(f"已记录申请:用户 {interaction.user.id},用户名 {username},角色 {target_role.name}") # 回复用户 await interaction.response.send_message(f'感谢**{username}**,你的申请已提交,已为你分配{target_role.name}角色!', ephemeral=True) else: await interaction.response.send_message('错误:无法找到目标角色', ephemeral=True) @bot.command() async def send_view(ctx): embed = discord.Embed(title='联盟角色申请') await ctx.send(embed=embed, view=ViewAllianceSelection()) bot.run('你的机器人Token')
关键要点
- 必须调用父类构造函数:
super().__init__(title=self.title)是核心,确保Modal的custom_id等必要属性被初始化。 - 自定义变量传递:通过
__init__参数传入角色ID,在on_submit中直接使用self.target_role_id即可。 - 组件添加方式:文本输入组件可放在
__init__里用self.add_item()添加,也可保持类属性定义,两种方式均有效。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

