使用后禁用按钮
disable a button after being used
最近我决定重写我的 discord 机器人并添加按钮。
到目前为止,我遇到的主要问题是,我无法在按下按钮后 禁用按钮 人们告诉我 button.disabled=True
实际上,它会禁用按钮, 但它只是将其发送为禁用状态,因此永远不能按下它。我想要的是能够单击它并执行它,然后禁用它。
作为参考,我会放一些代码
我使用 disnake,一个 discord.py 分支,它的语法确实与 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
(由于不一致的新特权意图,我迁移到斜线命令)只有成员能够按下它,没有其他人。
到目前为止一切正常,现在我们在命令中“assemble”之后
@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
在回调中,按钮将被禁用而不会被点击。我将回调放在命令中的主要原因是当按钮触发时能够使用嵌入,如果我把它放在子类按钮或视图中我不能再这样做了。
所以这就是我的全部问题,如果您知道更好的解决方法,包括使用嵌入,并且只有成员可以按下按钮,请告诉我,我花了一个多星期的时间来解决这个问题,我可以'没弄对
我倾向于并建议为每个视图回调创建新的 classes。这样我就可以更轻松地处理多个按钮,并且更易于阅读。随意相应地编辑我的代码,我会留下评论作为指导
首先,给您的 BlurpleButton 一个自定义 ID,或者让用户在 class
中定义一个
(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)
我使用 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 = iter.data["custom_id"]
[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
说明
您可以通过在按钮的回调中将 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
参数。
参考
最近我决定重写我的 discord 机器人并添加按钮。
到目前为止,我遇到的主要问题是,我无法在按下按钮后 禁用按钮 人们告诉我 button.disabled=True
实际上,它会禁用按钮, 但它只是将其发送为禁用状态,因此永远不能按下它。我想要的是能够单击它并执行它,然后禁用它。
作为参考,我会放一些代码
我使用 disnake,一个 discord.py 分支,它的语法确实与 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
(由于不一致的新特权意图,我迁移到斜线命令)只有成员能够按下它,没有其他人。
到目前为止一切正常,现在我们在命令中“assemble”之后
@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
在回调中,按钮将被禁用而不会被点击。我将回调放在命令中的主要原因是当按钮触发时能够使用嵌入,如果我把它放在子类按钮或视图中我不能再这样做了。
所以这就是我的全部问题,如果您知道更好的解决方法,包括使用嵌入,并且只有成员可以按下按钮,请告诉我,我花了一个多星期的时间来解决这个问题,我可以'没弄对
我倾向于并建议为每个视图回调创建新的 classes。这样我就可以更轻松地处理多个按钮,并且更易于阅读。随意相应地编辑我的代码,我会留下评论作为指导
首先,给您的 BlurpleButton 一个自定义 ID,或者让用户在 class
中定义一个(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)
我使用 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 = iter.data["custom_id"]
[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
说明
您可以通过在按钮的回调中将 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
参数。