Pycord开发RulesButton角色按钮触发TypeError报错求助
问题根因
你遇到的两个TypeError分别来自两个基础用法错误:
- 第一个报错:
RulesButton.__init__() takes 1 positional argument but 2 were given
你定义RulesButton类的构造函数时只声明了self一个入参,但实例化时传入了self.bot/self(Cog实例),参数数量不匹配。 - 第二个报错:
expected an instance of View not <class 'cogs.rules.RulesButton'>
Pycord的add_view()方法仅接受View子类/实例作为入参,Button是UI组件不能单独作为视图注册,必须挂载到View容器中才能注册持久化监听。
另外原代码还有一个逻辑隐患:注册持久化视图时必须设置timeout=None,否则视图超时后会停止监听按钮点击;原代码中role is None分支没有任何反馈,用户点击后会出现无响应的情况。
修复方案
- 移除实例化
RulesButton时多余的传参,当前按钮回调逻辑不需要调用bot实例,无需额外传入参数 - 持久化视图注册时,先创建
timeout=None的View实例,将按钮添加到View中后再传入add_view() - 确保发送规则消息和注册持久化视图时,按钮的
custom_id完全一致
修正后完整代码
import discord from discord.ext import commands from discord.ui import * from discord.ext.commands import Cog from botconfig.rules import * from botconfig.phrases import * class RulesButton(discord.ui.Button): def __init__(self): super().__init__( label="Accept the Rules here!", style=discord.enums.ButtonStyle.green, custom_id="interaction:RoleButton", ) async def callback(self, interaction: discord.Interaction): user = interaction.user role = interaction.guild.get_role(rules_id) if role is None: await interaction.response.send_message("❌ 角色配置异常,请联系管理员", ephemeral=True) return if role not in user.roles: await user.add_roles(role) await interaction.response.send_message("🎉 You accepted the Rules!", ephemeral=True) else: await interaction.response.send_message("❌ You already accepted the Rules!", ephemeral=True) class Rules(commands.Cog): def __init__(self, bot): self.bot = bot @commands.is_owner() @commands.command() async def rules(self, ctx: commands.Context): if isinstance(ctx.channel, discord.DMChannel): return view = discord.ui.View(timeout=None) # 移除多余的self.bot传参 view.add_item(RulesButton()) await ctx.send(f"{RULES_BILD_URL}") await ctx.send(f"{RULES_BESCHREIBUNG}", view=view) @commands.Cog.listener() async def on_ready(self): # 持久化视图注册需要传入View实例,不能直接传Button persistent_view = discord.ui.View(timeout=None) persistent_view.add_item(RulesButton()) self.bot.add_view(persistent_view) def setup(bot): bot.add_cog(Rules(bot))
扩展说明
如果后续需要在按钮回调中调用bot实例,可以给RulesButton的__init__添加bot入参,示例如下:
class RulesButton(discord.ui.Button): def __init__(self, bot): self.bot = bot super().__init__( label="Accept the Rules here!", style=discord.enums.ButtonStyle.green, custom_id="interaction:RoleButton", )
后续实例化时传入self.bot即可,不会再触发参数数量不匹配的报错。注意持久化视图注册不要放在Cog的__init__里,必须等on_ready事件触发后再注册,否则可能因为bot未完全初始化报错。
内容的提问来源于stack exchange,提问作者otherwiseGG
相关产品推荐
相关产品推荐

