如何在Discord模态框中留存用户输入信息,防止内容丢失?
解决Discord模态框编辑Embed时丢失之前输入内容的问题
问题根源
- 模态框每次打开都是全新实例,没有从现有Embed读取已有的footer文本、图标和timestamp状态填充到输入框,用户看不到之前的设置,容易误操作清空内容。
- 提交逻辑判断错误:
if self.ftext:是判断输入框对象是否存在,而非用户是否输入了内容,导致即使用户没改footer文本,也会用空值覆盖原内容。 - Timestamp处理强制覆盖:用户未填写time字段时,会直接把timestamp设为None,而非保留原有状态。
修复后的完整代码
import discord from discord import ui from datetime import datetime class FooterModal(ui.Modal, title="Edit Footer"): def __init__(self, embed: discord.Embed): super().__init__() # 读取现有Embed的footer信息 existing_footer_text = embed.footer.text if embed.footer.text else "" existing_footer_icon = embed.footer.icon_url if embed.footer.icon_url else "" # 读取现有timestamp状态,转换成Yes/No existing_timestamp = "Yes" if embed.timestamp else "No" # 将TextInput改为实例属性,动态设置默认值 self.ftext = ui.TextInput( label="Edit footer text", placeholder="Encourage life", style=discord.TextStyle.long, required=False, default=existing_footer_text # 填充现有文本 ) self.fticon = ui.TextInput( label="Edit footer image", placeholder="https://www.chickenCLT.png", style=discord.TextStyle.long, required=False, default=existing_footer_icon # 填充现有图标链接 ) self.time = ui.TextInput( label="Timestamp", placeholder="Yes/No", style=discord.TextStyle.short, min_length=2, max_length=6, required=False, default=existing_timestamp # 填充现有timestamp状态 ) async def on_submit(self, interaction: discord.Interaction): embed = interaction.message.embeds[0] # 仅当用户输入了新的footer文本或图标时,才更新footer update_footer = False new_footer_text = embed.footer.text new_footer_icon = embed.footer.icon_url if self.ftext.value.strip(): new_footer_text = self.ftext.value.strip() update_footer = True if self.fticon.value.strip(): new_footer_icon = self.fticon.value.strip() update_footer = True if update_footer: embed.set_footer(text=new_footer_text, icon_url=new_footer_icon) # 仅当用户明确输入Yes/No时,才修改timestamp if self.time.value.strip(): if self.time.value.lower() == "yes": embed.timestamp = datetime.now() else: embed.timestamp = None await interaction.message.edit(embed=embed) await interaction.response.send_message(".", delete_after=0.0001) class MainView(discord.ui.View): def __init__(self): super().__init__() @discord.ui.button(label="Edit Footer", style=discord.ButtonStyle.grey, custom_id="edit_footer") async def edit_footer(self, interaction: discord.Interaction, button: discord.ui.Button): # 获取当前消息的Embed,传入模态框初始化 current_embed = interaction.message.embeds[0] await interaction.response.send_modal(FooterModal(current_embed))
关键修复点
- 动态填充输入框默认值:将TextInput从类属性改为实例属性,初始化模态框时传入现有Embed,读取footer和timestamp的状态填充到输入框,用户打开模态框就能看到之前的设置。
- 优化提交逻辑:只在用户输入了有效内容时才对应更新Embed字段,避免未修改的字段被清空或覆盖。
- 保留原有状态:timestamp仅在用户明确输入Yes/No时才修改,未输入则保持原状态。
内容的提问来源于stack exchange,提问作者Janicooking
相关产品推荐
相关产品推荐

