Discord.py Cog中Interaction UI View异常:离婚命令按钮交互失效
Discord.py 离婚命令按钮交互及SQL操作修复方案
核心问题分析
- View初始化参数完全不匹配:创建
DivorceView时传入的参数是ctx, author_id, conjuge,但类定义的__init__参数顺序是author_id, conn, cursor,导致author_id被错误赋值为ctx对象,这就是打印时显示Context对象的原因。 - 数据库连接管理混乱:Cog中已创建数据库连接,View却重复创建新连接;且命令中提前关闭连接会导致后续操作失败。
- 缺少交互权限校验:未限制仅命令发起者可点击按钮,任何人都能操作。
- SQL操作存在语法错误:
divorce_query中self.conn.close未加括号,无法正确关闭连接;删除逻辑可简化优化。
修复步骤及完整代码
import discord from discord.ext import commands import sqlite3 from discord.ui import Button, View class marryCog(commands.Cog): def __init__(self, client): self.client = client # 初始化数据库连接,由Cog统一管理生命周期 self.conn = sqlite3.connect("./database/falsosdb.db") self.cursor = self.conn.cursor() @commands.command() async def divorce(self, ctx, conjuge: discord.Member = None): author_id = ctx.author.id # 构造确认Embed if conjuge is None: embed = discord.Embed(title="离婚确认", description=f"你确定要离婚吗?") else: embed = discord.Embed(title="离婚确认", description=f"你确定要和{conjuge.mention}离婚吗?") # 正确传递View所需参数:author_id、数据库连接和游标 message = await ctx.send(embed=embed, view=DivorceView(author_id, self.conn, self.cursor)) await ctx.message.delete() def cog_unload(self): # Cog卸载时统一关闭数据库连接 self.conn.close() class DivorceView(discord.ui.View): def __init__(self, author_id: int, conn, cursor): super().__init__(timeout=60) # 设置60秒超时,避免View永久占用资源 self.author_id = author_id self.conn = conn self.cursor = cursor @discord.ui.button(label="确认", style=discord.ButtonStyle.green) async def confirm_button(self, interaction: discord.Interaction, button: discord.ui.Button): self.divorce_query(self.author_id) await interaction.response.send_message("你已成功离婚", ephemeral=True) self.stop() @discord.ui.button(label="取消", style=discord.ButtonStyle.red) async def cancel_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message("离婚操作已取消", ephemeral=True) self.stop() async def interaction_check(self, interaction: discord.Interaction): # 仅允许命令发起者进行交互 return interaction.user.id == self.author_id def divorce_query(self, user_id): # 简化删除逻辑:直接删除与当前用户相关的所有婚姻记录 self.cursor.execute("DELETE FROM marry WHERE id_casado = ? OR id_conjuge = ?", (user_id, user_id)) self.conn.commit() # 连接由Cog统一关闭,此处不操作 async def setup(client): await client.add_cog(marryCog(client))
关键修复点说明
- 修正View参数传递:确保
DivorceView初始化时传入正确的author_id、数据库连接和游标,彻底解决参数错位导致的Context对象问题。 - 统一数据库连接管理:在Cog初始化时创建连接,卸载时关闭,避免重复创建连接和提前关闭导致的操作失败。
- 添加交互权限校验:启用
interaction_check方法,限制只有发起命令的用户能点击按钮,避免误操作。 - 优化SQL删除逻辑:直接根据用户ID删除相关记录,简化代码;修复
conn.close()的语法错误。 - 设置View超时:给View添加60秒超时,超时后按钮自动失效,避免资源浪费。
内容的提问来源于stack exchange,提问作者Kryszxt
相关产品推荐
相关产品推荐

