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

Discord.py Cog中Interaction UI View异常:离婚命令按钮交互失效

Discord.py 离婚命令按钮交互及SQL操作修复方案

核心问题分析

  1. View初始化参数完全不匹配:创建DivorceView时传入的参数是ctx, author_id, conjuge,但类定义的__init__参数顺序是author_id, conn, cursor,导致author_id被错误赋值为ctx对象,这就是打印时显示Context对象的原因。
  2. 数据库连接管理混乱:Cog中已创建数据库连接,View却重复创建新连接;且命令中提前关闭连接会导致后续操作失败。
  3. 缺少交互权限校验:未限制仅命令发起者可点击按钮,任何人都能操作。
  4. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:05:24