首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在nextcord中等待按钮按下或消息响应。

在nextcord中等待按钮按下或消息响应。
EN

Stack Overflow用户
提问于 2021-11-30 10:29:20
回答 1查看 1.1K关注 0票数 1

我需要一个函数,我们叫它button_or_text。如果按下按钮(很可能是str ),此函数将返回某个值。它返回消息已经发送的Message对象。

我试着做的是:

代码语言:javascript
复制
import nextcord
import nextcord.ext.commands as cmds

class Coggers(cmds.Cog):
    def __init__(self, bot):
        self.bot = bot

    @cmds.command()
    async def test(self, ctx: cmds.Context):
        async def button_or_text():
            class Buttons(nextcord.ui.View):
                def __init__(self):
                    super().__init__()
                    self.value = None
                
                @nextcord.ui.button(label="very mysterious button", style=nextcord.ButtonStyle.green)
                async def very_mysterious_button(self, button: nextcord.ui.Button, interact: nextcord.Interaction):
                    self.stop()
                    # insert function that somehow cancels the wait_for()
                    # return "some value"
        
            view = Buttons()
            await ctx.send("press this very mysterious button or send a message?", view=view)

            check = lambda msg: ctx.author.id == msg.author.id
            message = await self.bot.wait_for("message", check=check)

            return message.content

        
        print(await button_or_text())
        await ctx.send("end")


def setup(bot: cmds.Bot):
    bot.add_cog(Coggers(bot))

这里,我为这个函数做了一个wait_for。如果按下按钮,则以某种方式取消该wait_for,然后返回按下按钮的set值。如果发送了一条消息,则以某种方式阻止Buttons对象侦听,然后返回Message对象。

我在绞尽脑汁如何做wait_for取消和返回,但我觉得这不是最好的方法,我错过了一种更“优雅”的方式

有什么帮助吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-30 16:40:25

如果没有关于您到底想实现什么的所有细节,那么很难给出一个全面的解决方案,但以下是如何同时等待两个事件中的第一个事件的一般想法:

代码语言:javascript
复制
async def await_input(self):
    """waits for valid user input (message, button) and returns the corresponding payload
    """

    events = [
        self.bot.client.wait_for('message', check=self._check_msg),
        self.bot.client.wait_for('interaction', check=self._check_button)
    ]

    # with asyncio.FIRST_COMPLETED, this triggers as soon as one of the events is fired
    done, pending = await asyncio.wait(events, return_when=asyncio.FIRST_COMPLETED)
    event = done.pop().result()

    # cancel the other check
    for future in pending:
        future.cancel()

    # check if the event has the `application_id` attribute to determine if it was the button press or a message
    if hasattr(event, 'application_id'):
        return 'button pressed'  # or whatever you want to return there
    else:
        return event  # this will be the message

剩下要做的是实现_check_msg (这很可能是您已经拥有的lambda )和_check_button,以确保只获得您感兴趣的输入。您还可能希望为每个事件设置一个超时,除非要无限期地等待。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70167795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档