最近我决定重写我的不和谐机器人并添加按钮。 到目前为止我遇到的主要问题是,我无法禁用按钮按下后人们告诉我关于
button.disabled=True
并且实际上,它会禁用按钮,但它只是将其禁用,所以它永远不能被压。我想要的是能够单击它并执行它的操作,然后禁用它。
作为参考,我将放置一些代码
我使用disnake,一个discord.py fork,它的语法与dpy相同,但我们有按钮和斜线命令、下拉菜单等
class BlurpleButton(Button):
def __init__(self, label, emoji=None):
super().__init__(label=label, style=discord.ButtonStyle.blurple, emoji=emoji)
这是为了更容易使用按钮,我创建了一个模板,我可以在任何命令上使用它
class CustomView(View):
def __init__(self, member: disnake.Member):
self.member = member
super().__init__(timeout=180)
async def interaction_check(self, inter: disnake.MessageInteraction) -> bool:
if inter.author != self.member:
await inter.response.send_message(content="You don't have permission to press this button.", ephemeral=True)
return False
return True
这是为了只能由提到的成员按下的按钮,例如如果我这样做
/test @member
(由于不和谐新的特权意图,我迁移到斜杠命令)只有该成员才能按下它,其他人都无法按下它.
到目前为止一切正常,现在我们在命令中“组装”它之后
@commands.slash_command(description='test')
async def test(self, inter):
(do stuff in there)
. . .
button1 = BlurpleButton("Button name")
view=CustomView(member)
view.add_item(button1)
async def button_callback(inter):
await inter.send(embed=embedname2)
button1.callback = button_callback
await inter.send(embed=embed1, view=view)
现在,这段代码正在做它想要做的事情,发送一个嵌入(让我们只说我把......嵌入的位置很少)并附加到该嵌入,我们有
button1
,当点击它时,它会发送 embedname2
并且有些地方不再工作了,在发送embedname2
之后我继续以任何方式尝试,如果我在回调中添加button1.disabled=True
,则通过单击一次来禁用自身的按钮,该按钮只会被发送为禁用状态,而不会被点击。我将回调放在命令中的主要原因是能够在按钮触发时使用嵌入,如果我将其放在子类按钮或视图中,我就不能再这样做了。
所以这就是我的全部问题,如果您知道更好的解决方案,包括使用嵌入并且只有会员可以按下按钮,请告诉我,我花了一个多星期的时间试图解决这个问题,但我无法解决它
您可以通过在按钮回调中将
button.disabled
设置为 True
来实现此目的。然后,您还需要编辑原始消息以反映此更改。
@commands.slash_command(description='test')
async def test(self, slash_inter: disnake.ApplicationCommandInteraction, member: disnake.Member):
view = CustomView(member)
button1 = BlurpleButton("TEST")
view.add_item(button1)
async def button_callback(button_inter: disnake.MessageInteraction):
button1.disabled = True
await button_inter.send(embed=embedname2)
await slash_inter.edit_original_message(view=view)
button1.callback = button_callback
await slash_inter.send(embed=embed1, view=view)
注意:要使 /test @member 正常工作,您需要在斜杠命令中添加
disnake.Member
参数。
disnake.MessageInteraction
disnake.ui.Button.callback
我使用 Pycord,而不是 Disnake,但这应该可以。您可能必须在此处或按钮回调中更改确切的方法调用。
async def interaction_check(self, inter: disnake.MessageInteraction) -> bool:
if inter.author != self.member:
await inter.response.send_message(content="You don't have permission to press this button.", ephemeral=True)
return False
# The interaction is allowed, so let's disable the button.
# Interactions have a data field that stores the custom ID of the
# component sent the interaction. We will use this to find our button
# in the view.
button_id = inter.data["custom_id"] # instead of custom_id specify your own
[child for child in self.children if child.custom_id == button_id][0].disabled = True
await inter.edit_original_message(view=self)
# From this point on, you will be dealing with inter.followup, since
# an interaction can only be responded to once.
return True
我倾向于并且建议为每个视图回调创建新的类。这样我就可以更轻松地处理多个按钮,并且更容易阅读。请随意相应地编辑我的代码,我将留下评论作为指示
首先,为您的 BlurpleButton 指定一个自定义 ID,或者让用户在类中定义一个 ID
(label=label, style=discord.ButtonStyle.blurple, emoji=emoji, custom_id="bttn1") # bttn1 is your custom ID, you'll use it to select this button from the view when disabling it or modifying its contents
在回调中,尝试以下代码:
b = [x for x in self.children if x.custom_id == "bttn1"][0] # Selects the blurpleButton from the view's buttons based on the custom_id
b.disabled = True # Disable
然后通过这个新视图编辑您的消息来完成它
await inter.response.edit_message(view=self) # Edit that the buttons are attached to, but replacing the view with the new one containing our edits (disabling the button)