【问题标题】:How do I use wait_for in discord.py?如何在 discord.py 中使用 wait_for?
【发布时间】:2021-04-18 10:10:59
【问题描述】:

我正在制作一个充当漫画阅读器的命令,我想使用wait_for 等待用户的反应,然后相应地前进或后退。但是,我对如何实现它感到困惑。

@commands.command()
    async def read_manga(self, ctx, page=1):
        page -= 1
        image_urls = ['image1.url', 'image2.url', 'image3.url', 'etc.urls']

        message = await ctx.send(image_urls[page])

        def backward_check(reaction, user):
            return user == ctx.message.author and str(reaction.emoji) == '◀️'

        def forward_check(reaction, user):
            return user == ctx.message.author and str(reaction.emoji) == '▶️'
        
        try:
            reaction, user = await self.bot.wait_for('reaction_add', timeout=60.0, check=forward_check)
        except asyncio.TimeoutError:
            print('Timed Out')
        else:
            await message.edit(content=image_urls[page+1])

        try:
            reaction, user = await self.bot.wait_for('reaction_add', timeout=60.0, check=backward_check)
        except asyncio.TimeoutError:
            print('Timed Out')
        else:
            await message.edit(content=image_urls[page-1])

就像现在一样,机器人只会响应前向检查而不是后向检查。此外,如果我对 ▶️ 做出反应、未做出反应,然后再次对 ▶️ 做出反应,机器人将不会检测到。我该如何解决这些问题?

【问题讨论】:

  • 看起来您正在尝试实现一个菜单,您可以使用this 菜单扩展并省去一些麻烦

标签: python-3.x discord.py


【解决方案1】:

您的机器人正在等待响应,然后该命令结束。您可以使用while 循环来避免这种情况。

import asyncio
BUTTONS = ["◀️", "⏹", "▶️"]

@commands.command(name="read-manga")
async def read_manga(self, ctx):
  urls = ["url1.png", "url2.png"] #Your image urls
  index = 0
  msg = await ctx.send(urls[index])
  for b in BUTTONS:
    await msg.add_reaction(b)
  
  while True:
    try:
      react, user = await self.bot.wait_for("reaction_add", timeout=60.0, check=lambda r, u: r.message.id == msg.id and u.id == ctx.author.id and r.emoji in BUTTONS)
      await msg.remove_reaction(react.emoji, user) #Removes the user reaction after he/she reacts the message
    
    except asyncio.TimeoutError:
      return await msg.delete()

    else:
      if react.emoji == BUTTONS[0] and index > 0: #if current page is the first page this will not work
        index -= 1
      elif react.emoji == BUTTONS[1]:
        return await msg.delete()
      elif react.emoji == BUTTONS[2] and index < len(urls) - 1: #checking if current page is not the last one
        index += 1
      await msg.edit(content=urls[index]) #editing message content

【讨论】:

  • 您好,感谢您的回答。您可以编辑答案以包含一些代码吗?我想我知道你的意思,但我有点不确定。
  • 你能解释一下image_urls是什么。这是文本还是您正在尝试编辑图像?
  • 它们是 url,所以应该是文本。例如:https://i.imgur.com/0UvUEBz.jpghttps://i.imgur.com/LvAJaJ2.png
  • 我试过你的代码,它不会删除我的反应,也不会编辑消息内容。
  • 你能分享代码吗?我在我的机器人的帮助命令中使用这个嵌入并且没有发生错误。另外,我在async 之后添加了def,但您不需要使函数名称和命令名称相同。
【解决方案2】:

可以使用列表同时等待 2 个表情符号,并使用 lambda 函数而不是基本函数:

reaction, user = await self.bot.wait_for('reaction_add', timeout=60.0, check=lambda reaction, user: reaction.emoji in ['◀️','▶️'] and user == ctx.message.author)

你可以在 else 之后使用一些条件,例如:

else:
    if reaction == '◀️':
        ...
    else:
        ...

你可以用elif reaction == '▶️':代替else:,它是一样的。

【讨论】:

    【解决方案3】:

    感谢 Ceres 为我提供了指向 menu extension 的链接,我同意这可能是实现我想要实现的目标的更好方法。

    【讨论】:

      猜你喜欢
      • 2020-11-27
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      • 2021-09-10
      • 2021-07-03
      相关资源
      最近更新 更多